1. はじめに
まずは身近な例えから始めましょう。レシピを想像してください:
小麦粉、卵、砂糖を混ぜ、泡立て、油を加え、もう一度泡立てる。
ちょっと変に見えますか?では、「泡立てる」と「加える」の間に読点やかっこが入っているところを想像してみてください。手順の順番が一気にわかりやすくなります。
プログラミングでも、複雑な式を書くときに同じような状況が起こります:
boolean result = a > 0 && b < 10 || c == 3;
評価順序はどうなるでしょう?まず a > 0 && b < 10 が計算され、それから || c == 3 が続くのでしょうか?それとも逆でしょうか?
明確な評価順序がなければ、コンピュータが「材料を取り違え」、思わぬ結果になるかもしれません。
2. Java における演算子の優先順位
Java(多くのプログラミング言語と同様)には演算子の優先順位表があります。
優先順位が高い演算子は、低い演算子より先に評価されます。
その表の中で、(条件式に関する)最重要部分を見てみましょう:
| 演算子 | 説明 | 優先順位 |
|---|---|---|
|
かっこ | 最も高い |
|
論理「NOT」 | 高い |
|
等しい / 等しくない | 中 |
|
比較 | 中 |
|
論理「AND」 | 低い |
|
論理「OR」 | さらに低い |
(算術演算子もありますが—その優先順位は論理演算子より上です。)
重要なルール
「AND」(&&) の優先順位は「OR」(||) より高い
つまり、まず AND が評価され、そのあとで OR が評価されます。AND は論理積、OR は論理和だからです。
条件の評価順序のフローチャート
graph LR
A["a > 0"] --&&--> B["b < 10"]
B --||--> C["c == 3"]
(実際には: a > 0 && b < 10 || c == 3 — まず a > 0 && b < 10 が評価され、その結果が || で c == 3 と組み合わされます。)
3. 演算子の結合方向: 左から右、右から左
優先順位のほかに、もうひとつ重要な概念があります。それが結合性です。
同じ優先順位の演算子が「並んでいる」とき、どちらの方向から評価していくかを定める規則です。
例:
boolean a = true, b = false, c = true;
boolean result = a && b && c;
質問: どのように評価されるでしょうか?
答え: && の結合性は左から右です。
つまり、まず a && b を評価し、その結果を c と評価します。
条件式に関しては:
| 演算子 | 結合性 |
|---|---|
|
左から右 |
|
右から左 |
4. かっこは複雑な条件式の最良の味方
ここからが魔法(そして救い)の始まりです。式を書くとき、かっこは優先順位を変え、コードをより読みやすく、安全にしてくれます。
例1(かっこなし):
// 意図: 「ユーザーが成人かつ市民である」または「特別許可証を持っている」場合
boolean isAdult = age >= 18;
boolean isCitizen = country.equals("ベラルーシ");
boolean hasPermit = hasSpecialPass == true;
if (isAdult && isCitizen || hasPermit)
{
System.out.println("アクセスが許可されました!");
}
Java の評価:
まず isAdult && isCitizen を評価し、その結果を hasPermit と || で組み合わせます。
- たとえば、isAdult = true、isCitizen = false、hasPermit = true
- isAdult && isCitizen → true && false → false
- false || true → true
つまり、特別許可証があれば通過できます。
特別許可証がなくても、成人かつ市民であれば通過できます。
例2(かっこあり):
if (isAdult && (isCitizen || hasPermit))
{
System.out.println("アクセスが許可されました!");
}
この場合、まず isCitizen || hasPermit を評価し、その結果と isAdult を組み合わせます。
つまり、成人であることかつ(市民である、または特別許可証を持っている)ことが必要です。
かっこのわずかな違いが、ロジックに大きな違いをもたらします!
GO TO FULL VERSION