如何!=和==运算符在Java中使用整数?

以下代码似乎让我感到困惑,因为它提供了两个不同的输出。代码在jdk 1.7上进行了测试。

public class NotEq { public static void main(String[] args) { ver1(); System.out.println(); ver2(); } public static void ver1() { Integer a = 128; Integer b = 128; if (a == b) { System.out.println("Equal Object"); } if (a != b) { System.out.println("Different objects"); } if (a.equals(b)) { System.out.println("Meaningfully equal."); } } public static void ver2() { Integer i1 = 127; Integer i2 = 127; if (i1 == i2) { System.out.println("Equal Object"); } if (i1 != i2){ System.out.println("Different objects"); } if (i1.equals(i2)){ System.out.println("Meaningfully equal"); } } } 

输出:

[ver1输出]
不同的对象
有意义的平等。

[ver2输出]
平等对象
有意义的平等

为什么==和!=测试为ver1()和ver2()产生不同的结果,相同的数字远小于Integer.MAX_VALUE? 可以断定==检查大于127的数字(如代码中所示的整数包装类)是完全浪费时间吗?

对于-128到127之间的值缓存整数,因此Integer i = 127将始终返回相同的引用。 Integer j = 128不一定会这样做。 然后,您需要使用equals来测试底层int相等性。

这是Java语言规范的一部分 :

如果被装箱的值p为真,假,字节或范围为\ u0000到\ u007f的字符,或介于-128和127(含)之间的整数或短数,则让r1和r2为结果p的任何两个拳击转换。 始终是r1 == r2的情况。

但是对Integer j = 128 2次调用可能会返回相同的引用(不保证):

例如,较少内存限制的实现可以缓存所有char和short值,以及-32K到+ 32K范围内的int和long值。

因为小整数是用Java实现的,所以你尝试了“小”限制的不同侧面的数字。

默认情况下,存在-128和最多127的Integer对象缓存。 可以配置上边框。 上部缓存边界可由VM选项-XX:AutoBoxCacheMax=控制-XX:AutoBoxCacheMax=

您在使用表单时使用此缓存:

  Integer i1 = 127; 

要么

 Integer i1 = Integer.valueOf(127); 

但是当你使用的时候

 Integer i1 = new Integer(127); 

那么你肯定会得到一个新的未缓存对象。 在后一种情况下,两个版本都打印出相同的结果。 使用缓存版本可能会有所不同。

https://www.owasp.org/index.php/Java_gotchas

我从我的一位教授那里获得了这个链接,非常有用。

Java缓存从-128到127的整数这就是对象相同的原因。

我认为处理基元时的==和!=运算符将会影响你当前使用它们的方式,但是对于对象(Integer与int),你需要用.equals()方法进行测试。

我不确定这一点,但对于对象,==将测试一个对象是否是同一个对象,而.equals()将执行测试,这两个对象的值包含等价(或者方法需要是创建/覆盖自定义对象。