HOWTO · Java

Java の `!=` と `=!` の違い:不等比較と代入・論理否定

Java の不等比較演算子 `!=` と、代入に論理否定を組み合わせた `a = !b` の違いを、例を使って解説します。

このページの内容

Java の != は、左右の値が異なるときに true を返す不等比較演算子です。文字の並び =! は演算子ではありません。a = !b のような式では、Java は = を代入、! を論理否定として解釈し、b の否定結果を a に代入します。

以下の例では、比較の結果と、否定を組み合わせた代入が条件にどう影響するかを説明します。

Java の != による不等比較の例

!= を使うと、2つの値を比較できます。値が等しい場合は false、異なる場合は true を返します。数値などのプリミティブ型では値を比較し、参照型では参照先が異なるオブジェクトかどうかを比較します。等価比較の結果を否定するには !(a == b) と書けます。これは a != b と同じ真偽値になります。

この演算子の結果は真偽値なので、if 条件に直接使ったり、boolean 型の変数に格納したりできます。たとえば if (count != limit) は、2つのプリミティブ値が異なるときに実行されます。オブジェクトを比較する場合、!= が調べるのは内容ではなく同一性です。異なる String オブジェクトに同じ文字列が入っていても、同一性の比較では異なるものと判定されることがあります。オブジェクトの内容を比較したい場合は equals を使います。!(a == b) の括弧は、まず等価比較を行い、その結果を否定するという順序を明確にします。この書き方は長い条件を読むときに役立ちますが、通常は a != b のほうが簡潔です。

public class Main {
  public static void main(String[] args) {
    int a = 10;
    int b = 10;
    System.out.println(a != b);

    a = 20;
    System.out.println(a != b);
    System.out.println(!(a == b));
  }
}
false
true
true

最初の値の組では比較結果は false です。a を変更すると値が異なるため、不等比較と否定した等価比較のどちらも true になります。

Java での =! に見える代入と否定の例

Java に =! という複合演算子はありません。a = !b では、まず !b を評価し、その真偽値を a に代入します。同じ代入は if 条件にも書けます。この場合、条件の値は代入された真偽値になり、その値が true ならブロックが実行されます。この書き方は有効ですが、条件を調べながら a の値も変更します。代入する必要がない場合は、if (!b) のように条件を直接書くほうが読みやすいことがよくあります。

代入演算子は単項否定演算子より優先順位が低いため、この式は a = (!b) と解釈されます。代入式そのものも真偽値を持ち、a に格納した値を評価結果として返します。そのため、Java では代入式を if の条件として使えます。この条件は a を別の値と比較しているわけではありません。代入が意図した処理なら便利ですが、比較式だと思っていると予想外に感じることがあります。値の保存と条件判定の両方が必要なら、代入と判定を別々の文にすると、それぞれの処理が明確になります。

public class Main {
  public static void main(String[] args) {
    boolean a;
    boolean b = true;
    a = !b;
    System.out.println("a = " + a);

    b = false;
    if (a = !b) {
      System.out.println("condition is true; a = " + a);
    }
  }
}
a = false
condition is true; a = true

b が true のとき、!b は false になり、その値が a に代入されます。その後 b が false になると、条件内の代入によって a に true が格納されます。この true が条件の値となるため、if ブロックが実行されます。式を a = !b のように空白を入れて書くと代入と否定を見分けやすくなりますが、空白の有無で意味は変わりません。