演算子の分類
演算子は、対象となるオペランドの数によって以下の 3 つに大別されます。
- 単項演算子:オペランドが 1 つ(例:++a, !b)
- 二項演算子:オペランドが 2 つ(例:a + b, x == y)
- 三項演算子:オペランドが 3 つ(例:条件 ? 真の場合 : 偽の場合)
算術演算子
基本的な四則演算に加え、剰余算(%)およびインクリメント・デクリメント演算子が提供されます。
int count = 10;
int result = count++;
この場合、resultには 10 が代入され、その後countが 11 に更新されます。 postfix 演算子(後置)は、式の評価時に元の値を保持し、その後で変数自身を更新する仕組みです。
逆に、prefix 演算子(前置)は先に更新を行います。
int count = 10;
int result = ++count;
この場合、countが先に 11 となり、その値がresultに代入されます。
代入とインクリメントが混在する場合、評価順序に注意が必要です。
int k = 5;
k = k++;
上記コードの実行後、kの値は 5 のままです。これは、k++によって一時領域に元の値(5)が保存され、kが 6 に増分された後、代入演算により一時領域の値(5)が再度kに戻されるためです。
代入演算子
単純代入(=)のほか、複合代入演算子(+=, -=, *=, /=, %=)が利用可能です。複合代入では、暗黙的な型キャストが行われる点に注意が必要です。
byte value = 10;
value += 5; // コンパイル成功(暗黙のキャストが含まれる)
// value = value + 5; // コンパイルエラー(int 型になるため)
value += 5は内部的にvalue = (byte)(value + 5)として処理されるため、型エラーが発生しません。
関係演算子
大小比較や等値判定を行い、結果は boolean 型(true/false)で返されます。
- 比較:>, >=, <, <=
- 等値:==, !=
- 型判定:instanceof
論理演算子
boolean 値を結合し、条件分岐などで利用されます。
- & (AND):両方が true の場合 true
- | (OR):少なくとも一方が true の場合 true
- ^ (XOR):一方のみが true の場合 true
- ! (NOT):真偽を反転
- && (短絡 AND):左辺が false の場合、右辺を評価しない
- || (短絡 OR):左辺が true の場合、右辺を評価しない
短絡演算子は、結果が確定した時点で評価を停止するため、NullPointerException の回避や性能最適化に利用されます。
ビット演算子
整数値を二进制数として扱い、ビット単位での操作を行います。
- 論理ビット:&, |, ^, ~
- シフト演算:<< (左), >> (算術右), >>> (論理右)
整数は補数形式で記憶されます。正数の補数は符号ビットが 0 であり、負数は符号ビットが 1 です。
int a = 7; // 0000...0111
int b = 3; // 0000...0011
int ans = a & b; // 0000...0011 (結果は 3)
ビット反転演算子(~)は、符号を含めてすべてのビットを反転します。
int val = 5;
int inverted = ~val; // -6 となる
シフト演算は、乗除算の代替として利用可能です。
<< n:2 の n 乗を掛ける効果>> n:2 の n 乗で割る効果(符号を維持)>>> n:2 の n 乗で割る効果(符号を 0 で埋める)
負数の右シフトでは、>>は符号ビットを複製して埋めますが、>>>は常に 0 で埋めるため、結果が正数になる場合があります。
演算子の優先順位
式の評価順序は優先順位によって決定されます。一般的な順序は以下の通りです。
- 括弧 ()
- 単項演算子 (!, ++, --, ~)
- 算術演算子 (*, /, %, +, -)
- シフト演算子 (<<, >>, >>>)
- 関係演算子 (<, >, instanceof)
- 等値演算子 (==, !=)
- 論理演算子 (&, ^, |)
- 短絡演算子 (&&, ||)
- 代入演算子 (=, +=, ...)
複雑な式では、可読性を高めるために括弧を用いて明示的に順序を制御することが推奨されます。