三項演算子を理解する
条件演算子 ? : は、条件に応じて二つの式の一方から値を選びます。選んだ枝だけを実行する規則と、両方の枝から式の型を決める規則を分け、数値変換やnullの取り出しを追います。
この単元で学ぶこと
- 条件・true側・false側を区別する
- 選ばれた枝の副作用だけを追う
- 数値型とラッパーの組合せで式の型を求める
本文解説
値を選ぶ演算子 int age=20;String label=age>=18?"adult":"child";では条件がtrueなのでadultが代入されます。?の左が条件、?と:の間がtrue側、:の右がfalse側です。if文が処理を選ぶのに対し、ここでは式の値を選ぶので代入や引数の中で使えます。
条件は真偽値 int n=1;int x=n?10:20;はコンパイルできません。n!=0?10:20のようにbooleanを得る必要があります。Booleanの条件はアンボクシングされるため、Boolean ok=null;int x=ok?10:20;は条件評価時にNullPointerExceptionになります。
評価する枝は一つ int n=0;int x=true?++n:++n;ではtrue側だけを評価し、xもnも1です。両方の値を先に計算してから選ぶのではありません。int d=0;int x=d==0?0:10/d;ならゼロ除算の枝を避けます。
値を返す式が必要 true?System.out.print("A"):System.out.print("B")は両枝がvoidで値を持たず、条件式の選択値にできません。表示を選ぶならSystem.out.print(true?"A":"B");のように先に文字列を選びます。また使わない枝の未宣言名などもコンパイル時に検査されます。
両枝で数値型を決める System.out.print(true?1:2.0);は1.0です。選んだ値は1でも、intとdoubleの枝の組合せから式全体はdoubleです。int x=true?1:2.0;はdoubleをintへ暗黙代入できず失敗します。実行される枝だけの型で判断しません。
小さい整数型には特別な規則 byte b=1;var x=true?b:2;では2がbyte範囲に収まるint定数なので式の型はbyteです。しかしint n=2;var x=true?b:n;ではnは定数式でなく通常の数値昇格によりintになります。単に数字が小さいことと、型規則上の定数式であることは違います。
ラッパーと数値が混ざる場合 Integer n=null;int x=true?n:0;はintとIntegerを組み合わせた数値条件式なので選んだnを取り出す際に例外になります。Integer x=true?n:0;としても、式の型intを決める規則が先に働くので救済されません。nullを保ちたい場合は両枝の型や変換を明示的に検討します。
入れ子と読みやすさ int n=0;String s=n>0?"plus":n<0?"minus":"zero";はn>0?"plus":(n<0?"minus":"zero")と結合します。複数の判定を短く書けますが、枝の型も追えることが大切です。条件が複雑なら括弧やif文に分け、結果と副作用を確認します。
図解
重要ポイント
- 条件はbooleanまたはBoolean。
- 実行する枝は一つでも、両方の型を検査する。
- 数値条件式の型は選択前に両枝の型等から決まる。
- 入れ子の条件演算子は右から結合する。
間違えやすい点
- 選ばれた値の見た目だけで式全体の型を決めない。
- intとIntegerの組合せではnullの取り出しに注意する。
- voidのメソッド呼出しを選択値にはできない。
用語解説
- 条件演算子
- 条件 ? true時の式 : false時の式という三つのオペランドを持つ演算子。
- 数値昇格
- 数値演算等のためにオペランドの型を規則に従って揃える変換。
- 定数式
- コンパイル時に値が決まる所定の式。数値条件式の型決定にも影響する。
関連教材
参考資料
教材データに登録された参考リンクです。リンク先の内容や更新日は提供元でご確認ください。
- https://www.oracle.com/jp/education/certification/javase-17-programmer-1/
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-14.html#jls-14.4
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-5.html#jls-5.1.8
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.23
- https://docs.oracle.com/javase/specs/jls/se17/html/jls-15.html#jls-15.25
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/Integer.html
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Objects.html
- https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/ArrayList.html
確認問題の出題・採点や学習履歴の保存にはログインが必要です。