PR

Java:演算子の基本を3分で1からおさらい

Java

Javaにおいて演算子(operator)はプログラムのロジックを組み立てる上で非常に重要な役割を果たします。数値計算、条件分岐、ビット操作、オブジェクトの参照など、さまざまな用途に合わせた演算子が用意されており、その正しい使い方を理解することは、Java開発において必須です。

本記事では、以下の項目について詳しく解説します。

  • 算術演算子
  • 関係演算子(比較演算子)
  • 論理演算子
  • ビット演算子
  • 代入演算子
  • その他の演算子(単項演算子、条件演算子、 instanceof など)
  • 演算子の優先順位と結合規則
スポンサーリンク

算術演算子

算術演算子は、数値データを操作するための基本的な演算子です。主なものとして、以下が挙げられます。

加算(+)

  • 機能: 二つの数値を加算する。
int a = 5;
int b = 3;
int sum = a + b; // sumは8になる

減算(-)

  • 機能: 一方の数値からもう一方の数値を減算する。
int a = 10;
int b = 4;
int diff = a - b; // diffは6になる

乗算(*)

  • 機能: 二つの数値を乗算する。
int a = 7;
int b = 6;
int product = a * b; // productは42になる

除算(/)

  • 機能: 一方の数値をもう一方の数値で除算する。
  • :
int a = 20;
int b = 4;
int quotient = a / b; // quotientは5になる

整数同士の除算では、余りは切り捨てられます。ただし、データ型が浮動小数点数の場合は小数点以下も計算される、という点に注意が必要です。

剰余(%)

  • 機能: 割り算の余りを求める。
int a = 17;
int b = 5;
int remainder = a % b; // remainderは2になる

剰余は偶数・奇数の判定などに利用したりするのがよくある使い方です。

関係演算子(比較演算子)

関係演算子は、二つの値を比較し、真(true)または偽(false)の論理値を返します。条件分岐(if文やループ)でよく使用されます。

等価(==)と不等価(!=)

  • 等価(==): 二つの値が等しい場合にtrueを返す。
int a = 5;
int b = 5;
boolean result = (a == b); // true
  • 不等価(!=): 二つの値が異なる場合にtrueを返す。
int a = 5;
int b = 3;
boolean result = (a != b); // true

オブジェクトの場合、==は参照の同一性を比較するため、値の比較には.equals()メソッドを使う必要がある点を押さえておきましょう、

大小比較(<, >, <=, >=)

  • 機能: 数値の大小を比較する。
int a = 7;
int b = 10;
boolean isLess = (a < b);  // true
boolean isGreaterOrEqual = (a >= b); // false

論理演算子

論理演算子は、真偽値を組み合わせて複雑な条件式を作る際に利用されます。

論理積(AND:&&)

  • 機能: 両方の条件がtrueの場合のみtrueとなる。
boolean a = true;
boolean b = false;
boolean result = a && b; // false

論理和(OR:||)

  • 機能: どちらか一方でもtrueの場合はtrueとなる。
boolean a = true;
boolean b = false;
boolean result = a || b; // true

否定(NOT:!)

  • 機能: 真偽値を反転する。
boolean a = true;
boolean result = !a; // false

参考 ショートカット演算子

Javaの論理演算子の一部は ショートカット演算子(短絡評価演算子) と呼ばれる場合があります。これは、評価の途中で結果が確定した場合に、後続の処理をスキップする演算子のことです。

  • &&(論理積 AND):左側の式が false なら、右側の式を評価せずfalse を返す
  • ||(論理和 OR):左側の式が true なら、右側の式を評価せずtrue を返す
public class ShortCircuitExample {
    public static void main(String[] args) {
        int x = 0;
        
        // 左側が false なので右側(++x > 5)は評価されない
        boolean result = (x > 5) && (++x > 5);
        
        System.out.println("result: " + result); // false
        System.out.println("x: " + x);           // 0(インクリメントされていない)
    }
}

この例では、x > 5false であるため、その時点で「論理積は成立しない」と判断されます。したがって、後続の ++x > 5 は評価されません。その結果、変数 x はインクリメントされずに 0 のままとなります。これは、不要な計算を省き、効率を高める「短絡評価」の典型的な動作例です。一方、ビット演算子(&)を用いた場合は必ず両方の式を評価し、++x が実行される点が異なります。

ビット演算子

ビット演算子は、整数の各ビット単位での演算を行います。低レベルのデータ操作や、パフォーマンス重視の場面で用いられます。

ビットAND(&)

  • 機能: 各ビットごとにAND演算を行う。
int a = 0b1010; // 10
int b = 0b1100; // 12
int result = a & b; // 0b1000 -> 8

ビットOR(|)

  • 機能: 各ビットごとにOR演算を行う。
int a = 0b1010;
int b = 0b1100;
int result = a | b; // 0b1110 -> 14

ビットXOR(^)

  • 機能: 各ビットごとに排他的OR演算を行う。
int a = 0b1010;
int b = 0b1100;
int result = a ^ b; // 0b0110 -> 6

ビット反転(~)

  • 機能: 全ビットを反転させる(ビット単位のNOT)。
int a = 0b1010;
int result = ~a; // aのビットが全て反転される

シフト演算子(<<, >>, >>>)

  • 左シフト(<<): 指定したビット数だけ左にシフトし、右側は0で埋める。
  • 右シフト(>>): 符号付きの右シフト。符号ビットを維持しながら右にシフトする。
  • 論理右シフト(>>>): 符号に関係なく右にシフトし、左側は常に0で埋める。
int a = 5; // 0b0101
int result = a << 2; // 0b010100 -> 20

int b = 20;
int result = b >> 2; // 5になる

int c = -20;
int result = c >>> 2; // 負の数のビットパターンが0で埋められる

代入演算子

代入演算子は、変数に値を代入するための演算子です。さらに、複合代入演算子を使うことで、演算と代入を同時に行うことができます。

基本の代入(=)

  • 機能: 右側の値を左側の変数に代入する。
int a = 10;

複合代入演算子(+=, -=, *=, /=, %=, など)

  • 機能: 変数に対して演算を行い、その結果を再度同じ変数に代入する。
  • 例(+=)
int a = 5;
a += 3; // aは8になる

その他の演算子

Javaには、上記以外にもさまざまな演算子があります。ここでは特に注意すべきものを解説します。

単項演算子(インクリメント/デクリメント、正負演算子など)

  • インクリメント(++)とデクリメント(--):
    • 前置型(例:++a): 演算子の実行後に評価される。
    • 後置型(例:a++): 評価後に演算子が実行される。
int a = 5;
int b = ++a; // aとbは共に6になる
int c = a--; // cは6、aは5になる

インクリメント演算子はちょいとややこしいので補足しておきます。

以下のサンプルコードでは、変数 num に対して前置・後置のインクリメント/デクリメント演算子を使った例を一度に示します。出力結果を見比べることで、どのタイミングで数値が変化しているかを確認できます。

重要なポイントは以下。

  • インクリメント演算子 (++) とデクリメント演算子 (--) は、変数の値を 1 ずつ増減させる。
  • 前置演算子 (++a / --a) は「値を先に変化させてから式を評価」します。
  • 後置演算子 (a++ / a--) は「式を評価した後に値を変化」させます。
public class IncrementDecrementExample {
    public static void main(String[] args) {
        int num = 5;

        System.out.println("初期値: " + num); // 5

        // 後置インクリメント
        System.out.println("num++: " + num++); // 5 が表示された後、num は 6 に
        System.out.println("num の現在値: " + num); // 6

        // 前置インクリメント
        System.out.println("++num: " + ++num); // まず num が 7 に、次に 7 を表示
        System.out.println("num の現在値: " + num); // 7

        // 後置デクリメント
        System.out.println("num--: " + num--); // 7 が表示された後、num は 6 に
        System.out.println("num の現在値: " + num); // 6

        // 前置デクリメント
        System.out.println("--num: " + --num); // まず num が 5 に、次に 5 を表示
        System.out.println("num の現在値: " + num); // 5
    }
}

/*
初期値: 5
num++: 5
num の現在値: 6
++num: 7
num の現在値: 7
num--: 7
num の現在値: 6
--num: 5
num の現在値: 5
*/
  • 正負演算子(+、-):
    • 数値の符号を示す。単項の「-」は値を反転させる。
int a = 5;
int b = -a; // bは-5になる

条件演算子(三項演算子: ? : )

  • 機能: 条件に応じて二つの値のうち一つを選択する。
  • 構文
条件 ? 真の場合の値 : 偽の場合の値;
int a = 10;
int b = 20;
int max = (a > b) ? a : b; // maxは20になる

instanceof 演算子

  • 機能: オブジェクトが特定のクラスまたはインターフェースのインスタンスであるかどうかを判定する。
Object obj = "Java";
if (obj instanceof String) {
    System.out.println("objはString型です。");
}

キャスト(型変換)

  • 機能: あるデータ型の値を別の型に変換する。特にプリミティブ型とオブジェクト型(参考 プリミティブ型とは?)の変換で用いられる。
double d = 9.78;
int i = (int) d; // iは9になる(小数点以下が切り捨て)

演算子の優先順位と結合規則

Javaでは、複数の演算子を組み合わせる際に、どの演算子を先に評価するかが明確に定義されています。これを理解することで、意図した通りの計算結果が得られるようになります。

優先順位の概要

  • 高い優先順位: 単項演算子(++、--、!、~、キャストなど)が最も高く、次いで乗算・除算・剰余、加算・減算、シフト演算子、比較演算子、論理演算子、条件演算子、代入演算子の順となります。
  • 結合規則: 多くの演算子は左結合ですが、代入演算子や条件演算子は右結合です。
int a = 5;
a = a = 10; // 右結合なので、右側から評価される

括弧の活用

  • 複雑な式の場合、明示的に括弧()を用いることで評価順序を明確にすることができます。
int result = (2 + 3) * 4; // 括弧により2+3が先に計算され、結果は20になる
タイトルとURLをコピーしました