3.

Java 演算子完全ガイド — 算術・論理・ビット・三項

編集
この記事の要点
  • Java の演算子は 算術 / 関係 / 論理 / ビット / 代入 / 三項 / instanceof など
  • 短絡評価: &&|| は左から評価し、結果が確定すれば右は評価しない
  • 整数除算は小数を捨てる: 5 / 2 == 2。浮動小数なら 5.0 / 2 == 2.5
  • ビット演算: & | ^ ~ << >> >>>>>> は符号無し右シフト
  • Java 14+ switch 式、Java 16+ pattern matching instanceof で書き方が大きく変わった

演算子の分類

分類演算子
算術+ - * / % ++ --a + b / i++
関係 (比較)== != < > <= >=a == b
論理&& || !a && b
ビット& | ^ ~ << >> >>>flags & MASK
代入 / 複合代入= += -= *= /= %= &= |= ^= <<= >>=x += 1
三項 (条件)? :a > 0 ? "正" : "負"
型判定instanceofo instanceof String
文字列結合+"a" + "b"

算術演算子

int a = 10, b = 3;
System.out.println(a + b);  // 13
System.out.println(a - b);  // 7
System.out.println(a * b);  // 30
System.out.println(a / b);  // 3   ★ 整数除算 (切り捨て)
System.out.println(a % b);  // 1   剰余

// 浮動小数の除算
System.out.println(10.0 / 3);   // 3.3333...
System.out.println(10 / 3.0);   // 3.3333... (片方が double なら double)

// インクリメント / デクリメント
int i = 5;
System.out.println(i++);  // 5 (後置: 出力してから加算)
System.out.println(++i);  // 7 (前置: 加算してから出力)

// オーバーフロー
int max = Integer.MAX_VALUE;
System.out.println(max + 1);  // -2147483648 (折り返し)

// long リテラルは末尾 L
long big = 10000000000L;

関係 / 論理演算子と短絡評価

int x = 5;
System.out.println(x > 0 && x < 10);   // true
System.out.println(x < 0 || x > 100);  // false

// 短絡評価: 左で確定すれば右は評価しない
String s = null;
if (s != null && s.length() > 0) {  // ★ 安全 (s が null なら length() を呼ばない)
    System.out.println(s);
}

// & | は短絡しない (ビット演算も兼ねる)
if (s != null & s.length() > 0) {  // ★ s が null なら NullPointerException
}

// ! (否定)
boolean active = true;
if (!active) { ... }

ビット演算子

演算子名称例 (8bit)
&AND0b1100 & 0b1010 = 0b1000
|OR0b1100 | 0b1010 = 0b1110
^XOR0b1100 ^ 0b1010 = 0b0110
~NOT (反転)~0b00001100 = 0b11110011
<<左シフト1 << 3 = 8
>>算術右シフト-8 >> 1 = -4 (符号維持)
>>>論理右シフト-1 >>> 1 = Integer.MAX_VALUE (符号無視)
int flags = 0b1011;
int MASK_READ  = 0b0001;
int MASK_WRITE = 0b0010;
int MASK_EXEC  = 0b0100;

boolean canRead  = (flags & MASK_READ)  != 0;  // true
boolean canWrite = (flags & MASK_WRITE) != 0;  // true
boolean canExec  = (flags & MASK_EXEC)  != 0;  // false

// フラグの追加 / 削除
flags |= MASK_EXEC;   // 追加
flags &= ~MASK_WRITE; // 削除
flags ^= MASK_READ;   // トグル

// 高速な 2 倍 / 1/2
int n = 10;
System.out.println(n << 1);   // 20 (× 2)
System.out.println(n >> 1);   // 5  (÷ 2)

代入と複合代入

int x = 10;
x += 5;   // x = x + 5  → 15
x -= 3;   // 12
x *= 2;   // 24
x /= 4;   // 6
x %= 4;   // 2

// ★ 複合代入は暗黙のキャストを行う
byte b = 10;
// b = b + 1;     // ★ コンパイルエラー (int → byte の暗黙キャスト不可)
b += 1;           // ✅ OK (暗黙キャスト含む)

// 連鎖代入
int a, b1, c;
a = b1 = c = 0;   // 全部 0

三項演算子 と switch 式 (Java 14+)

// 三項演算子
int n = 5;
String result = n > 0 ? "正" : (n < 0 ? "負" : "ゼロ");

// ✅ Java 14+ switch 式 (アロー記法、break 不要)
String day = "MONDAY";
int workHours = switch (day) {
    case "SATURDAY", "SUNDAY" -> 0;
    case "FRIDAY"             -> 6;
    default                   -> 8;
};

// ブロック付き (複数行 + yield で値を返す)
int n2 = 5;
String label = switch (n2) {
    case 1, 2, 3 -> "小";
    case 4, 5, 6 -> {
        System.out.println("中間");
        yield "中";
    }
    default -> "大";
};

instanceof と pattern matching (Java 16+)

Object o = "Hello";

// 旧来 (Java 15 以前)
if (o instanceof String) {
    String s = (String) o;
    System.out.println(s.length());
}

// ✅ Java 16+ pattern matching for instanceof
if (o instanceof String s) {
    System.out.println(s.length());  // 自動キャスト
}

// switch でのパターンマッチ (Java 21+)
String describe(Object o) {
    return switch (o) {
        case Integer i -> "int: " + i;
        case String  s -> "str: " + s;
        case null      -> "null!";
        default        -> "other";
    };
}

演算子の優先順位 (高い順)

順位演算子
1後置 ++ --
2前置 ++ -- + - ! ~ / 型キャスト
3* / %
4+ -
5<< >> >>>
6< > <= >= instanceof
7== !=
8&
9^
10|
11&&
12||
13? :
14= += -= *= ...

覚えにくいので迷ったら括弧 ()。可読性のためにも積極的に。

文字列結合 +

String name = "Taro";
int age = 25;
String msg = "Name: " + name + ", Age: " + age;

// 数値 + 数値 + 文字列 の評価順に注意
System.out.println(1 + 2 + "abc");  // "3abc"
System.out.println("abc" + 1 + 2);  // "abc12"

// ループ内連結は StringBuilder を使う
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 1000; i++) {
    sb.append(i).append(",");
}
String result = sb.toString();

FAQ

Q: ==.equals() の違い
A: == は参照の同一性、.equals() は内容の等価性。文字列比較は必ず .equals()

Q: &&& はどちらを使うべき?
A: 論理判定なら必ず && (短絡で安全 & 高速)。& はビット演算用、または「両辺を必ず評価したい」特殊ケース。

Q: 整数を浮動小数で割りたい
A: 片方を double にキャスト: (double) a / b または a / (double) b

編集
Post Share
子ページ
  1. 算術演算子
  2. 文字列演算子
  3. 代入演算子
  4. 比較演算子
  5. 論理演算子
  6. ビット演算子
同階層のページ
  1. 基本的なルール
  2. 変数
  3. 演算子
  4. 標準ライブラリ
  5. 外部ライブラリ
  6. 制御構文
  7. リスト(配列)
  8. タプル
  9. セット
  10. 辞書(dict)
  11. クラスとメソッド
  12. 継承の概念と必要性
  13. 継承の構文
  14. コンストラクタ
  15. cookieの値の設定と取得
  16. 例外処理
  17. 例外を文字列で出力する方法
  18. httpリクエスト(curl)をする方法
  19. Responseオブジェクトの中身の確認
  20. 変数が空かどうか判定する方法
  21. タイムゾーンの設定と現在日時の取得と文字列化
  22. シングルクォーテーションとダブルクォーテーションの違い

最近更新/作成されたページ