はじめに
Javaの二項演算子は、2つの値を組み合わせて計算、比較、条件判定、ビット単位の処理を行うための記号です。初心者が最初につまずきやすいのは、+や-のような見た目が分かりやすい演算と、&&、||、<<のように評価順や型変換まで関係する演算を同じ感覚で読んでしまう点にあります。そのため、二項演算子の使い方は、記号を暗記するよりも「左辺と右辺に何を置き、結果がどの型になるか」で整理すると理解しやすくなります。
公式ドキュメントによれば、Javaの演算子には優先順位があり、同じ式の中では優先順位の高い演算から評価されますが、これは押さえたい点です。詳しい優先順位はOracle Java Tutorials Operatorsで確認できます。仕様上の評価順や式の意味はJava Language Specification Chapter 15にまとまっているのが基本です。
関連する型や構文を並行して確認したい場合は、Java List型の基礎、Javaアノテーションの考え方、Javaでの条件判定、Javaエスケープ処理、Javaのオーバーライドも合わせて読むと、サンプルコード内の文脈を追いやすくなります。
- Java 21
- OpenJDK 21 / 標準ライブラリのみ
- Javaの二項演算子が受け取る2つの値と戻り値の考え方
- 算術、比較、論理、ビット演算の使い方と読み方
- 初心者が間違えやすい0除算、浮動小数点数、優先順位の注意点
- サンプルコードを使った条件判定、フラグ管理、ストリーム処理の組み立て方
- 演算処理をメソッドやラムダ式でカスタマイズする考え方
Javaの二項演算子とは
a + bのように、左側の値と右側の値を受け取って結果を返す記号が二項演算子です。Javaでは、値そのものをint、double、boolean、Stringなどの型として扱うため、同じ記号でも組み合わせる型によって意味が変わります。たとえば+は数値なら加算ですが、片方がStringなら文字列結合になります。
これを理解するには、演算子だけでなくオペランドの型を見る必要があるのがポイントです。そのため、初心者は「記号の名前」だけでなく「左辺、演算子、右辺、結果の型」を並べて読むのが現実的です。演算の結果は変数へ代入したり、if文の条件に使ったり、returnでメソッドの戻り値にしたりできます。
二項演算子の基本概念
Javaでよく使う二項演算子は、算術演算子、比較演算子、論理演算子、ビット演算子、代入を伴う複合代入演算子に分けると整理しやすくなります。算術演算子は+、-、*、/、%で数値の演算を行い、比較演算子は==、!=、<、>、<=、>=でtrueまたはfalseを返するのが一般的です。
一方、論理演算子の&&と||はboolean同士を組み合わせる場面で使います。ビット演算子の&、|、^、<<、>>、>>>は整数をビット列として扱うため、フラグ管理や低レイヤ寄りの処理で見かけます。+=、-=、*=、/=、%=、&=、|=のような複合代入は、演算と代入を短く書く構文です。
| 分類 | 主な演算子 | 戻り値 | 使いどころ | 注意点 |
|---|---|---|---|---|
| 算術 | + - * / % | 数値 | 四則演算、余りの計算 | int同士の/は整数除算 |
| 比較 | == != < > <= >= | boolean | 条件分岐、ループ判定 | 参照型の同値判定はequalsも検討 |
| 論理 | && || | boolean | 複数条件の結合 | 短絡評価により右辺が評価されない場合あり |
| ビット | & | ^ | 整数またはboolean | フラグ管理、ビット単位の処理 | &&や||と混同しない |
| シフト | << >> >>> | 整数 | 2の累乗倍、符号付きビット移動 | 負数では符号ビットの扱いに注意 |
| 複合代入 | += -= |= | 代入後の値 | 累積、設定追加 | 暗黙の型変換が関係する場合あり |
この分類を押さえると、サンプルコードを読むときに式の目的を先に推測できます。たとえばscore >= 80 && passedなら、比較で得たbooleanと別のbooleanを論理積で結合している式だと分かります。演算子の優先順位が不安な場合は、()で評価したいまとまりを明示すると読み間違いを減らせますし、ここがポイントです。
💡 Tips: 二項演算子の式は、左辺、演算子、右辺、結果の型の順で読むと整理しやすくなるのが現実的です。特に初心者は、==が代入ではなく比較である点を早めに区別すると、条件分岐の読み取りが安定します。
二項演算子の使い方
二項演算子の使い方は、変数に値を入れ、式で演算し、結果を別の変数や条件式に渡す流れで確認できます。Javaではmainメソッドに小さなサンプルコードを書けば、クラス単位で挙動を追いやすくなると整理できます。ただし、コードの出力例は環境で実行した事実ではなく、記述から導ける期待される出力として扱いるのが目安です。
サンプルコード1:算術演算子を使う
算術演算子は、数値を扱うJavaコードの入口になります。int同士の足し算、引き算、掛け算、割り算、剰余を同じ場所で確認すると、/と%の違いも見えやすくなります。
結果: 期待される変数の値は、sumが30、diffが-10、productが200、quotientが5、remainderが1です。
このサンプルコードでは、num1とnum2を使って基本的な演算をまとめています。そのため、初心者はquotientが小数ではなく整数になる点に注意すると、後の0除算や型変換の説明へつながります。
サンプルコード2:比較演算子を用いた数値の比較
比較演算子は、数値の大小関係や等しさをbooleanで返すると理解できます。条件分岐のifや繰り返しのwhileでは、この結果が処理を分ける基準になります。
結果: 期待される値は、isEqualがfalse、isNotEqualがtrue、isGreaterがfalse、isSmallerがtrue、isGreaterOrEqualがfalse、isSmallerOrEqualがtrueです。
これらの式は、左辺と右辺を比較して真偽値を作ります。一方、=は代入、==は比較なので、条件式で=を書いてしまうミスはJava初心者に多い注意点です。
サンプルコード3:論理演算子を用いた条件判定
論理演算子は、複数の条件をまとめるときに使います。&&は両方がtrueのときだけtrueになり、||はどちらか一方がtrueならtrueになると覚えるとよいでしょう。
結果: 期待される値は、andResultがfalse、orResultがtrue、notResultがfalseです。
この例ではcondition1がtrue、condition2がfalseなので、論理積と論理和の違いがはっきり出ます。ただし、!は単項演算子であり、二項演算子ではないため、条件の反転に使う補助的な記号として分けて覚えるとよいです。
サンプルコード4:ビット演算を試す
ビット演算は、整数を2進数の並びとして見たときに、各桁を組み合わせる演算です。&は両方のビットが1の位置だけを残し、|はどちらかが1なら1にし、^は片方だけが1の位置を1にします。
結果: 期待される値は、andBitwiseが1、orBitwiseが7、notBitwiseが-6、xorBitwiseが6です。
このサンプルコードには~も含まれていますが、~num1は1つの値だけを反転する単項演算子です。そのため、二項演算子として見るべき中心はnum1 & num2、num1 | num2、num1 ^ num2になります。
二項演算子の応用例
基礎の演算が読めるようになると、メソッド化、条件分岐、フラグ管理、シフト処理へ応用できます。Javaの二項演算子は単独で完結する記号ではなく、class、staticメソッド、if、System.out.printlnなどと組み合わせて処理の意味を作りますし、これが一つの目安です。
サンプルコード5:算術演算子を使った簡易計算機
四則演算をメソッドに分けると、演算子の役割と処理の名前が対応します。除算だけは分母が0になる可能性があるため、Double.NaNを返す分岐を入れています。
結果: 期待される出力は、8、2、15、1.6666666666666667の順です。
このJavaコードでは、add、subtract、multiply、divideがそれぞれ演算の役割を持ちます。特に(double) a / bのようにキャストを入れると、整数除算ではなく小数を含む結果を扱えます。
サンプルコード6:複数の条件を組み合わせて判定する
複数条件の判定では、比較演算子で作ったbooleanと、既存のboolean変数を論理演算子で結合すると考えられます。業務ロジックでは点数、権限、在庫、有効期限などの条件をまとめて判定する形がよく見られます。
結果: 期待される出力は素晴らしい!です。
この例ではscore > 80がtrueになり、isHandsomeもtrueです。そのため、最初のif条件であるscore > 80 && isHandsomeが成立します。
サンプルコード7:ビットフラグを活用した設定の管理
ビットフラグは、複数のオンオフ設定を1つの整数に詰め込む方法です。NOTIFY、DARK_MODE、VOICE_RECOGのように異なるビット位置を割り当てると、|=で設定を追加し、&で含まれているかを判定できると言えるでしょう。
結果: 期待される出力は、通知が有効です。、ダークモードが有効です。、音声認識は無効です。です。
このJavaコードでは、settingsの各ビットが設定項目を表します。ビット演算によるカスタマイズはメモリ効率の面で扱いやすい場合がありますが、項目が増えると可読性が落ちるため、EnumSetなどの代替も検討できます。
サンプルコード8:シフト演算を使った高速計算テクニック
シフト演算は、整数のビット列を左右に移動する演算です。左シフトの<<は2の累乗倍と対応するため、1 << 3は8になるのが基本です。
結果: 期待される出力は2の3乗は8です。です。
ただし、現代のJITコンパイラは単純な乗算を最適化できるため、読みやすさを犠牲にしてまでシフト演算へ置き換える必要はありません。そのため、<<は高速化の記号として暗記するより、ビット位置を扱う演算として理解するほうが実用的です。
注意点と対処法
二項演算子の注意点は、見た目の短さに対して結果が型、評価順、例外、丸め誤差に左右されるところです。Javaではintの0除算でArithmeticExceptionが発生し、doubleの比較では2進表現の都合で期待した等価判定にならない場合があります。
そのため、初心者は「計算式が短いから安全」と考えず、分母、型、比較方法を確認する習慣を持つとよいです。特に押さえたいのは、/、%、==、&&の周辺で発生しやすい不具合です。
サンプルコード9:割り算のときの0除算を避ける
整数の割り算では、分母が0になると処理が例外で中断します。分母が外部入力、設定値、計算途中の値に由来する場合は、割り算の前に条件判定を置くのが基本になるのが目安です。
結果: 期待される出力は0で割ることはできません。です。
この対処法では、denominator != 0で安全に割れるかを先に判定しています。一方、doubleの0除算ではInfinityやNaNになるケースがあるため、整数と浮動小数点数の違いも合わせて確認すると理解が深まります。
サンプルコード10:浮動小数点数の比較における注意
浮動小数点数は、多くの小数を2進数で正確に表せません。そのため、0.1 + 0.2と0.3を==で直接比較すると、数学上の期待と異なる結果になる場合があるのがポイントです。
結果: 期待される出力はほぼ等しいです。
このサンプルコードでは、Math.abs(a - b)で差の絶対値を求め、EPSILONより小さいかを判定します。ただし、許容誤差の値は扱う金額、測定値、座標などの性質によって変わるため、用途に合わせた設計が必要です。
doubleの丸め誤差が問題になりやすいため、BigDecimalの利用を検討します。二項演算子の使い方だけでなく、型の選択も結果の正確さに関わりますが、覚えておくと役立つでしょう。カスタマイズ方法
JavaはC++のような演算子オーバーロードを提供していません。そのため、独自の演算を作りたい場合は、メソッド、インターフェース、ラムダ式、ストリームAPIを使って処理を表現します。
こうしたカスタマイズでは、記号そのものを増やすのではなく、add、compare、reduceのように名前付きの処理へ置き換えます。サンプルコードを追うと、二項演算子の役割をメソッド境界の中に閉じ込める考え方が分かりますし、ここを基本と考えるとよいでしょう。
サンプルコード11:カスタム演算子を定義する
独自型の加算を表したい場合、Javaでは+を再定義できないため、メソッドで同等の意味を持たせます。ベクトル同士の加算なら、x成分とy成分をそれぞれ足した新しいVectorを返す形になります。
結果: 期待される出力はResult: (6, 8)です。
このJavaコードでは、v1.add(v2)がベクトル加算の役割を持ちます。ただし、公開フィールドのpublic int x, yは学習用として短く書かれているため、実用コードではprivate finalやアクセサを使う設計も候補になります。
サンプルコード12:ラムダ式との連携
ラムダ式を使うと、比較や計算のルールを値のように渡せますし、ここがポイントです。Comparator<Integer>は2つのIntegerを受け取り、大小関係をintで返すため、二項演算子を含む比較ロジックと相性があります。
結果: 期待される出力は比較結果: 1です。
この例では3 % 2が1、4 % 2が0なので、差は1になります。元記事の説明にある-1とは符号が逆になるため、式の読み取りでは剰余の結果を順に追う必要があります。
サンプルコード13:ストリームAPIでの演算子の活用
ストリームAPIでは、複数の値を順に畳み込む処理で演算を扱えますが、これは押さえたい点です。IntStream.range(1, 6)は1から5までの整数を作り、reduceで合計値にまとめます。
結果: 期待される出力は合計: 15です。
このサンプルコードでは、Integer::sumが2つの整数を受け取って足す処理として使われます。明示的にa + bを書かなくても、reduceの中では二項演算に相当する処理が繰り返されていると理解できます。
reduceは、初期値と結合処理を組み合わせて値を集約するのが一般的です。合計以外にも最大値、最小値、積、独自集計などへカスタマイズできます。まとめ
Javaの二項演算子は、2つの値を受け取り、計算結果や真偽値を返す構文です。算術、比較、論理、ビット、シフト、複合代入を分けて読むと、サンプルコード内の式が何をしているか判断しやすくなります。
その理解を実用に近づけるには、演算子の記号だけでなく、型と評価順を合わせて見る必要があるのが現実的です。int同士の割り算、doubleの比較、&&の短絡評価、&と&&の違いは、初心者が早い段階で押さえたい注意点です。
カスタマイズの場面では、Javaに演算子オーバーロードがないため、メソッド、ラムダ式、ストリームAPIで処理を表します。Vector.add、Comparator.compare、IntStream.reduceのように名前を付けることで、複雑な演算でも読みやすい形にできます。
二項演算子の使い方を身につけると、条件分岐、計算処理、設定管理、集計処理のコードを読み書きしやすくなると整理できます。サンプルコードを小さく動かす前提で読み、期待される出力と式の関係を照合すると、Javaの演算に対する理解が安定します。
関連記事
- Java List型完全ガイド!初心者でもマスターできる7つのステップ
- Javaアノテーションの12選!初心者から上級者まで徹底ガイド
- Javaでうるう年を判定!初心者でも分かる9ステップ解説
- Javaエスケープ処理の10ステップマスターガイド
- Javaでマスターする!オーバーライドのたった7つのステップ
※本記事は実在のエンジニア複数名で構成される Japanシーモア編集部が、AI支援を活用して作成・校正・公開しています。


