3

我想知道这两者之间的区别:

Integer I = 30;  // is it autoboxing?

Integer I = new Integer(30);  // I know it is autoboxing
4

2 回答 2

6

它们是有区别的。第一个将被视为

Integer I = Integer.valueOf(30);  // autoboxing

这将使用一个Integer已经存储在内部缓存中的对象(当自动装箱值在 -127 到 128 范围内时是这样的)。第二个将显式创建一个 Integer对象。

你可以自己看看:

Integer I1 = 30;
Integer I2 = 30;

System.out.println(I1 == I2);
真的

对比

Integer I1 = new Integer(30);
Integer I2 = new Integer(30);

System.out.println(I1 == I2);
错误的

一般来说,不要将Integer对象与==因为测试引用相等性进行比较。我在这里使用它来测试是否I1I2引用相同的实例。在第一个片段中,它们这样做是因为Integer对应int 30的 缓存中已经存在,并且此实例被使用并分配给两者I1I2。在第二个片段中,它们没有,因为我们通过创建两个独立的对象new

顺便说一下,第二种情况不涉及自动装箱,您只是在创建一个简单的新对象。在第一种情况下存在自动装箱,因为 anint被隐式转换为Integer.

您实际上可以通过查看编译后的字节码来查看自动装箱的效果javap -c MyClass

于 2013-09-22T14:44:34.793 回答
2

在你写的第一行

Integer I = 30;

乍一看,您将一个整数(所有没有显式类型后缀的数字文字都视为整数)分配给一个对象,您认为编译器应该抱怨不兼容的类型。但事实并非如此,那么这就是神奇发生的地方 -> auto boxing!编译器自动将整数装箱30到 objectI中,即它创建一个保存整数值的 Object 并将其30分配给您的引用。

在行

Integer I = new Integer(30);

您显式使用new来创建对象。所以你不会让编译器有任何机会做任何事情。实际上,是什么确定这是auto boxing

除此之外,jvm 缓存了一系列常量值,以最小化用于这些常量的内存,从而提高性能。要使用此功能,您应该使用该valueOf()方法获取此类对象的实例。在这种情况下,对于相同的整数值,将返回一个唯一对象。如果你使用newthen 为同一个常量创建它,你每次都会得到一个不同的对象。

于 2013-09-22T15:00:29.110 回答