我想知道这两者之间的区别:
Integer I = 30; // is it autoboxing?
Integer I = new Integer(30); // I know it is autoboxing
我想知道这两者之间的区别:
Integer I = 30; // is it autoboxing?
Integer I = new Integer(30); // I know it is autoboxing
它们是有区别的。第一个将被视为
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
对象与==
因为测试引用相等性进行比较。我在这里使用它来测试是否I1
并I2
引用相同的实例。在第一个片段中,它们这样做是因为Integer
对应int
30
的 缓存中已经存在,并且此实例被使用并分配给两者I1
和I2
。在第二个片段中,它们没有,因为我们通过创建两个独立的对象new
。
顺便说一下,第二种情况不涉及自动装箱,您只是在创建一个简单的新对象。在第一种情况下存在自动装箱,因为 anint
被隐式转换为Integer
.
您实际上可以通过查看编译后的字节码来查看自动装箱的效果javap -c MyClass
。
在你写的第一行
Integer I = 30;
乍一看,您将一个整数(所有没有显式类型后缀的数字文字都视为整数)分配给一个对象,您认为编译器应该抱怨不兼容的类型。但事实并非如此,那么这就是神奇发生的地方 -> auto boxing
!编译器自动将整数装箱30
到 objectI
中,即它创建一个保存整数值的 Object 并将其30
分配给您的引用。
在行
Integer I = new Integer(30);
您显式使用new
来创建对象。所以你不会让编译器有任何机会做任何事情。实际上,是什么确定这是auto boxing
?
除此之外,jvm 缓存了一系列常量值,以最小化用于这些常量的内存,从而提高性能。要使用此功能,您应该使用该valueOf()
方法获取此类对象的实例。在这种情况下,对于相同的整数值,将返回一个唯一对象。如果你使用new
then 为同一个常量创建它,你每次都会得到一个不同的对象。