11

以下代码对我来说似乎真的很混乱,因为它提供了两个不同的输出。代码在 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 输出]
Equal Object
有意义地相等

为什么 == 和 != 测试会为 ver1() 和 ver2() 产生不同的结果,而相同的数字远小于 Integer.MAX_VALUE?是否可以得出结论 == 检查大于 127 的数字(对于代码中显示的 Integer 等包装类)完全是浪费时间?

4

5 回答 5

10

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

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

如果被装箱的值 p 是真、假、一个字节或 \u0000 到 \u007f 范围内的一个字符,或者一个介于 -128 和 127(含)之间的 int 或短数字,则令 r1 和 r2 为p 的任意两个拳击转换。r1 == r2 总是如此。

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

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

于 2012-03-22T14:17:01.337 回答
4

因为小整数在 Java 中被实习,并且您尝试了“小”限制不同侧的数字。

于 2012-03-22T14:16:02.830 回答
3

默认情况下,存在从 -128 到 127 的整数对象缓存。可以配置上边框。上缓存边界可以通过VM选项控制-XX:AutoBoxCacheMax=<size>

当您使用以下表单时,您正在使用此缓存:

 Integer i1 = 127;

或者

Integer i1 = Integer.valueOf(127);

但是当你使用

Integer i1 = new Integer(127);

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

于 2012-03-22T14:24:33.740 回答
0

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

于 2012-03-22T14:18:01.800 回答
0

我认为 == 和 != 运算符在处理原语时将按照您当前使用它们的方式工作,但是对于对象(整数与 int),您需要使用 .equals() 方法执行测试。

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

于 2012-03-22T14:19:26.087 回答