15

所以今天被问到这个问题。

Integer a = 3;
Integer b = 2;
Integer c = 5;
Integer d = a + b;
System.out.println(c == d);

这个程序会打印出什么?它返回真。我回答说,由于我对自动(和自动取消)装箱的理解,它总是会打印出错误的。我的印象是分配 Integer a = 3 将创建一个新的 Integer(3) 以便 == 将评估引用而不是原始值。

谁能解释一下?

4

4 回答 4

20

缓存 -128 到 127 之间的装箱值。装箱使用Integer.valueOf方法,它使用缓存。超出范围的值不会被缓存,并且总是作为新实例创建。由于您的值属于缓存范围,因此使用 == 运算符的值相等。

引用 Java 语言规范:

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

http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.1.7

于 2010-01-07T15:33:01.973 回答
11

这是真正发生的事情:

Integer c = Integer.valueOf(5);
Integer d = Integer.valueOf(a.intValue() + b.intValue());

Java 维护了一个Integer介于 -128 和 127 之间的对象缓存。与以下内容进行比较:

Integer a = 300;
Integer b = 200;
Integer c = 500;
Integer d = a + b;
System.out.println(c == d);

哪个应该打印false

于 2010-01-07T15:34:48.660 回答
5

这是因为一些(自动装箱的)整数被缓存了,所以你实际上是在比较相同的参考——这篇文章有更详细的例子和解释。

于 2010-01-07T15:36:29.487 回答
4

缓存也发生在自动装箱之外,考虑一下:

Integer a = 1;
Integer b = new Integer(1);
Integer c = Integer.valueOf(1);

System.out.println(a == b);
System.out.println(b == c);
System.out.println(c == a);

这将打印:

false
false
true

所以我想通常你想在比较对象时远离'=='

于 2010-01-07T15:50:37.740 回答