相等运算符()

==!= 运算符是二元运算符,根据操作数是否相等来计算 truefalse。如果操作数相等,则 == 运算符给出 true,否则给出 false。如果操作数相等,则 != 运算符给出 false,否则给出 true

这些运算符可以使用具有原始类型和引用类型的操作数,但行为明显不同。根据 JLS,实际上有三组不同的运算符:

  • 布尔 ==!= 运算符。
  • 数字 ==!= 运算符。
  • 参考 ==!= 运算符。

但是,在所有情况下,==!= 运算符的结果类型都是 boolean

数字 ==!= 运算符

==!= 运算符的一个(或两个)操作数是原始数字类型(byteshortcharint, longfloatdouble)时,运算符是数字比较。第二个操作数必须是基本数字类型或盒装数字类型。

其他数字运算符的行为如下:

  1. 如果其中一个操作数是盒装类型,则将其取消装箱。
  2. 如果其中一个操作数现在是 byteshortchar,它将被提升为 int
  3. 如果操作数的类型不相同,则具有较小类型的操作数被提升为较大类型。
  4. 然后进行如下比较:
    • 如果提升的操作数是 intlong,则测试这些值以查看它们是否相同。
    • 如果晋升的操作数是 floatdouble 那么:
      • 两个版本的零(+0.0-0.0)被视为相等
      • NaN 值被视为不等于任何东西,并且
      • 如果其 IEEE 754 表示相同,则其他值相等。

注意:使用 ==!= 比较浮点值时需要注意。

布尔 ==!= 运算符

如果两个操作数都是 boolean,或者一个是 boolean 而另一个是 Boolean,则这些操作符是布尔 ==!= 运算符。行为如下:

  1. 如果其中一个操作数是 Boolean,则它是未装箱的。
  2. 测试未装箱的操作数,并根据以下真值表计算布尔结果
A B A == B A != B
false false true false
false true false true
true false false true
true true true false

有两个陷阱使得使用 ==!= 谨慎使用真值:

参考 ==!= 运算符

如果两个操作数都是对象引用,则 ==!= 运算符将测试两个操作数是否引用同一对象。这通常不是你想要的。为了测试两个对象是否等于由值,所述方法 .equals() 应该使用。

String s1 = "We are equal";
String s2 = new String("We are equal");

s1.equals(s2); // true

// WARNING - don't use == or != with String values
s1 == s2;      // false

警告: 在大多数情况下,使用 ==!= 来比较 String 值是不正确的 ; 请参阅 http://stackoverflow.com/documentation/java/4388/java-pitfalls/16290/using-to-compare-strings 。类似的问题适用于原始包装类型; 请参阅 http://stackoverflow.com/documentation/java/4388/java-pitfalls/8996/using-to-compare-primitive-wrappers-objects-such-as-integer

关于 NaN 边缘案例

JLS 15.21.1 声明如下:

如果任一操作数是 NaN,那么 == 的结果是 false 但是 != 的结果是 true。事实上,当且仅当 x 的值为 NaN 时,测试 x != x 才是 true

这种行为(对大多数程序员来说)是出乎意料的。如果你测试 NaN 值是否等于它自己,答案是“不,它不是!”。换句话说,== 对于 NaN 值并不反身

但是,这不是 Java奇怪,这种行为在 IEEE 754 浮点标准中指定,你会发现它是由大多数现代编程语言实现的。 (有关更多信息,请参阅 http://stackoverflow.com/a/1573715/139985 …注意这是由做出决定时在房间里的人写的!)