この記事でわかること
-
三項演算子の正しい構文と評価順序
-
**優先順位(precedence)と結合規則(右結合)**の実務的な注意点
-
型推論・数値変換・共通スーパータイプの決まり
-
NPE/可読性劣化/文字列結合の落とし穴と回避策
-
Optional・Streams・switch式と比較した使いどころ
-
そのまま使えるNG→OKの書き換え集とコピペ集
基本構文
-
条件がtrueなら左側、falseなら右側を返す -
式なので値を返す(
if-elseは文)。よって、メソッド引数や代入右辺に置ける
評価順序と短絡評価(lazy evaluation)
-
条件を評価して真偽が決まった側だけが評価される(短絡評価) -
コストの高い計算やメソッド呼び出しを片側に逃がす最適化に使える
優先順位と結合規則(超重要)
-
三項演算子
?:の優先順位は||よりも低い、代入よりは高い -
右結合(right-associative):
a ? b : c ? d : eはa ? b : (c ? d : e)と解釈される
よくある誤読を防ぐ括弧
型の決まりごと(共通スーパータイプ・数値昇格・ボクシング)
-
2つの候補の型を整合させて共通の型にする
-
数値は**数値昇格(numeric promotion)**が起こる(例:
intとlong→long) -
参照型は共通スーパータイプに寄せる(例:
StringとObject→Object) -
条件はboolean。
Booleanを使うとアンボクシングNPEに注意
どんなときに使う?
-
値を返す条件分岐を一行で書きたい
-
引数やreturnで簡潔に条件分岐したい
-
デフォルト値の付与(null/空対策)をコンパクトに記述したい
NG→OK 書き換えパターン集
1) ネスト地獄
NG
OK(switch式 or メソッド抽出)
備考:Java 14+ の switch式(→後述)
2) 条件の再計算
NG
OK(1回だけ評価+右結合を明示)
3) 文字列結合の曖昧さ
NG
OK(括弧で意図を固定)
4) Boolean のアンボクシングNPE
NG
OK
Optional/Objectsとの比較と併用
デフォルト値付与
-
簡潔さ優先:三項演算子 or
Objects.* -
複雑ロジック・チェーン:
Optionalが読みやすいことが多い
Streamでの使いどころ
-
1行で分類ラベルを作るのに便利
-
複雑になったら関数抽出やswitch式へ
switch式(Java 14+)との使い分け
三項演算子が向くケース
-
Booleanベースの二択で短い結果値
-
返す値の型が一意で明確
switch式が向くケース
-
3パターン以上の分岐
-
網羅性や分岐ごとの処理ブロックが必要
-
break/returnミスを避けたい(switch式は式として値を返す)
フォーマット・コーディング規約の指針
-
空白を入れて読みやすく:
cond ? a : b -
括弧で明示:演算子優先順位に依存させない
-
ネストは2段まで。超えたら
if/switch式/ 関数抽出 -
副作用を含む呼び出しは片側のみにし、重複評価を避ける
よくある落とし穴チェックリスト
-
BooleanのアンボクシングNPEが起きないか -
文字列連結の結合順序は明確か(括弧!)
-
型整合(数値昇格・共通スーパータイプ)が意図通りか
-
再計算していないか(高コスト関数は一度だけ)
-
ネストが深くないか(2段ルール)
実務コピペ集
真偽の二択を返す
デフォルト値(null/空文字)
数値の正負ゼロ判定ラベル
条件付きフォーマット
Mapの値を安全取得
パフォーマンスの豆知識
-
JIT最適化により
if-elseと同等の性能が期待できる場面が多い -
差が問題になるケースは稀。可読性を優先し、必要ならベンチマークで確認
ミニFAQ
Q1. 三項演算子は可読性が悪い?
A. 短い二択なら可読。ネストや副作用が増えると悪化するので、2段を超えたら if / switch式 / メソッド抽出へ。
Q2. 返り値の型が左右で違うとどうなる?
A. 数値なら数値昇格、参照型なら共通スーパータイプに寄ります。意図がブレる場合はキャストや設計の見直しを。
Q3. var と併用して大丈夫?
A. OK。ただし推論された型が期待と一致しているか注意。IDEヒントや型注釈で明示すると安全。
Q4. 例外処理と混ぜてよい?
A. 可能ですが、三項演算子内に throw を混ぜると読みにくいです。if で分けるか、Objects.requireNonNull などを検討。
まとめ
-
三項演算子は**「短い二択」を式として**返すのが得意
-
右結合・優先順位・型整合の3点を押さえ、括弧で意図を固定する
-
複雑化したらswitch式やメソッド抽出に切り替える
-
NPE(特に
Booleanのアンボクシング)と再計算には要注意
