三項演算子(Java)
条件式を1行で書ける演算子です。『Java』の三項演算子は 条件 ? 真の値 : 偽の値 の形式で、if / else を簡潔に表現できます。値を返す「式」であるため変数への代入や引数として直接使えますが、型の一致が必要な制約やネストによる可読性の問題など、使いどころを理解することが重要です。
構文
// 基本構文です
// 条件式がtrueなら真の値を、falseなら偽の値を返します
変数 = 条件式 ? 真の値 : 偽の値;
// if / else との対応関係です
// 以下の2つは同じ意味です
// if / else で書いた場合
if (条件式) {
変数 = 真の値;
} else {
変数 = 偽の値;
}
// 三項演算子で書いた場合
変数 = 条件式 ? 真の値 : 偽の値;
// メソッドの引数に直接渡せます
System.out.println(条件式 ? "真のとき" : "偽のとき");
// 返り値として使えます
return 条件式 ? 真の値 : 偽の値;
if / else との使い分け
| 項目 | 三項演算子 | if / else |
|---|---|---|
| 記述量 | 1行で書けます。 | 複数行になります。 |
| 値の返却 | 「式」なので値を返せます。変数への代入・引数・returnに使えます。 | 「文」なので値を直接返せません。 |
| 複数処理 | 1つの値(式)しか書けません。 | 複数の処理をブロック内に書けます。 |
| 可読性 | 単純な条件なら簡潔です。ネストすると読みにくくなります。 | 複雑な条件でも読みやすいです。 |
| 型制約 | 真の値と偽の値の型が一致している必要があります。 | 型の一致は不要です。 |
サンプルコード
TernaryBasic.java
public class TernaryBasic {
public static void main(String[] args) {
// --- 基本的な三項演算子 ---
// 呪力量(cursedEnergy)が1000以上かどうかで等級を判定します
int cursedEnergy = 1500;
// if / else で書いた場合
String gradeIf;
if (cursedEnergy >= 1000) {
gradeIf = "上位等級";
} else {
gradeIf = "一般等級";
}
System.out.println("if/else: " + gradeIf);
// 三項演算子で書いた場合(同じ結果です)
String gradeTernary = cursedEnergy >= 1000 ? "上位等級" : "一般等級";
System.out.println("三項演算子: " + gradeTernary); // 『上位等級』と出力されます
// --- メソッドの引数に直接渡す ---
// 変数に代入せず、そのまま println に渡せます
boolean hasDomain = false;
System.out.println("領域展開: " + (hasDomain ? "使用可能" : "未習得")); // 『未習得』と出力されます
// --- returnに使う ---
System.out.println(getStatusLabel("虎杖悠仁", 1800));
System.out.println(getStatusLabel("釘崎野薔薇", 600));
// --- 型の一致が必要な例 ---
// 真の値と偽の値は同じ型(またはキャスト可能な型)でなければなりません
int hp = 50;
// 以下はString同士なので問題ありません
String hpStatus = hp > 0 ? "生存中" : "戦闘不能";
System.out.println("HP状態: " + hpStatus); // 『生存中』と出力されます
}
// returnに三項演算子を使うメソッドです
static String getStatusLabel(String name, int energy) {
return energy >= 1000 ? name + "は上位呪術師です。" : name + "は一般呪術師です。";
}
}
javac TernaryBasic.java java TernaryBasic if/else: 上位等級 三項演算子: 上位等級 領域展開: 未習得 虎杖悠仁は上位呪術師です。 釘崎野薔薇は一般呪術師です。 HP状態: 生存中
TernaryNested.java
public class TernaryNested {
public static void main(String[] args) {
// --- ネストした三項演算子(可読性が低下するため注意)---
// 呪術師の等級を表す整数から等級名を返す例です
// ネストすると式が長くなり、読み解くのに時間がかかります
int grade = 2;
// ネストした三項演算子(可読性が低い書き方です)
String gradeName = grade == 1 ? "1等級(七海建人レベル)"
: grade == 2 ? "2等級(虎杖悠仁レベル)" // ここが選択されます
: grade == 3 ? "3等級"
: grade == 4 ? "4等級"
: "特1等級または不明";
System.out.println("等級: " + gradeName);
// 上記は switch式(Java 14〜)を使うとより読みやすくなります
String gradeNameSwitch = switch (grade) {
case 1 -> "1等級(七海建人レベル)";
case 2 -> "2等級(虎杖悠仁レベル)"; // ここが選択されます
case 3 -> "3等級";
case 4 -> "4等級";
default -> "特1等級または不明";
};
System.out.println("等級(switch式): " + gradeNameSwitch);
// --- 三項演算子は単純な2分岐に留めるのがベストプラクティス ---
// 3分岐以上になる場合はif/elseまたはswitch式が使われることが多い
boolean isSorcerer = true;
String role = isSorcerer ? "呪術師" : "一般人";
System.out.println("役割: " + role); // 『呪術師』と出力されます
}
}
javac TernaryNested.java java TernaryNested 等級: 2等級(虎杖悠仁レベル) 等級(switch式): 2等級(虎杖悠仁レベル) 役割: 呪術師
TernaryOptional.java
import java.util.Optional;
public class TernaryOptional {
public static void main(String[] args) {
// --- 三項演算子と Optional.ofNullable の使い分け ---
// null の可能性がある値を扱う場面での比較です
// 呪術師のニックネームがnullになる可能性がある例です
String nickname = null; // 五条悟のニックネームは未設定とします
// 三項演算子でnullチェックする場合
String displayNameTernary = nickname != null ? nickname : "ニックネームなし";
System.out.println("三項演算子: " + displayNameTernary); // 『ニックネームなし』と出力されます
// Optional.ofNullable を使う場合
// nullかもしれない値をOptionalで包み、orElseでデフォルト値を指定します
String displayNameOptional = Optional.ofNullable(nickname).orElse("ニックネームなし");
System.out.println("Optional: " + displayNameOptional); // 『ニックネームなし』と出力されます
// --- 値がある場合の挙動確認 ---
String existingNickname = "最強";
String result1 = existingNickname != null ? existingNickname : "ニックネームなし";
String result2 = Optional.ofNullable(existingNickname).orElse("ニックネームなし");
System.out.println("三項演算子(値あり): " + result1); // 『最強』と出力されます
System.out.println("Optional(値あり): " + result2); // 『最強』と出力されます
// --- Optional を使う利点 ---
// orElseGet でデフォルト値を遅延評価できます(デフォルト値の生成コストが高い場合に有効)
String lazyDefault = Optional.ofNullable(nickname)
.orElseGet(() -> "ニックネームをDBから取得(遅延評価)");
System.out.println("orElseGet: " + lazyDefault);
// map で変換処理を安全にチェーンできます(値がnullでも例外が発生しません)
Optional.ofNullable(existingNickname)
.map(s -> "〈" + s + "〉")
.ifPresent(s -> System.out.println("装飾後: " + s)); // 『〈最強〉』と出力されます
}
}
javac TernaryOptional.java java TernaryOptional 三項演算子: ニックネームなし Optional: ニックネームなし 三項演算子(値あり): 最強 Optional(値あり): 最強 orElseGet: ニックネームをDBから取得(遅延評価) 装飾後: 〈最強〉
概要
三項演算子は「式」であるため、if / else(文)では直接できない変数への代入・メソッド引数への渡し・return での返却が1行で書けます。真の値と偽の値の型が一致していない場合、コンパイルエラーになるか意図しない型変換が行われることがあります。たとえば true ? 1 : "文字列" のように int と String を混在させるとコンパイルエラーになります。
ネストした三項演算子は処理の追跡が難しくなるため、3分岐以上になる場合は if / else if や switch式(Java 14〜)を使うほうが保守性が高まります。switch式の詳細は『switch文 / switch式』を参照してください。
null チェックの用途では三項演算子(value != null ? value : default)と Optional.ofNullable(value).orElse(default) のどちらも使えます。単純な null の置き換えなら三項演算子で十分ですが、値の変換(map)や遅延評価(orElseGet)が必要な場合は Optional が適しています。Optional の詳細については『Optional』を参照してください。
記事の間違いや著作権の侵害等ございましたらお手数ですがこちらまでご連絡頂ければ幸いです。