这里假设你对Java的基本类型和对应的包装器之间自动拆箱和装箱已经有所了解。但是这里强调一点,自动的拆箱和装箱是编译器在生成类的字节码时插入适当的方法调用来实现的。也就是说,我们可以反编译class文件,看看编译器插入了什么适当的方法来实现自动装箱和拆箱的。来看一个例子:
public class Test {
public static void main(String[] args) {
int i1 = 1;
int i2 = 1;
Integer integer1 = new Integer(1);
Integer integer2 = new Integer(1);
System.out.println(i1 == i2);// true
// integer1拆箱
System.out.println(i1 == integer1);// true
// i装箱
System.out.println(integer1.equals(i1));// true
// 两个对象地址不一样
System.out.println(integer1 == integer2);// false
// 两个对象值一样
System.out.println(integer1.equals(integer2));// true
// 自动装箱规范要求boolean、byte、char <= 127, 介于
// -128~127之间的short和int被包装到固定对象中,也就是
// 说,这些范围内的相同值对应同一个对象
Integer integer3 = 10;
Integer integer4 = 10;
System.out.println(integer3 == integer4); // true
Integer integer5 = 1000;
Integer integer6 = 1000;
System.out.println(integer5 == integer6); // false
}
}
运行结果如下(在类中也有标注):
true
true
true
false
true
true
如果对上面的例子会有这样的结果已经清楚了,就没必要往下看了;如果还有疑惑,我们可以看看这个类生成的class文件的反编译文件的内容:
import java.io.PrintStream;
public class Test
{
public static void main(String[] args)
{
int i1 = 1;
int i2 = 1;
Integer integer1 = new Integer(1);
Integer integer2 = new Integer(1);
System.out.println(i1 == i2);
System.out.println(i1 == integer1.intValue());
System.out.println(integer1.equals(Integer.valueOf(i1)));
System.out.println(integer1 == integer2);
System.out.println(integer1.equals(integer2));
Integer integer3 = Integer.valueOf(10);
Integer integer4 = Integer.valueOf(10);
System.out.println(integer3 == integer4);
Integer integer5 = Integer.valueOf(1000);
Integer integer6 = Integer.valueOf(1000);
System.out.println(integer5 == integer6);
}
}
顺便给出Integer类的equal方法:
public boolean equals(Object obj) {
if (obj instanceof Integer) {
// value是该包装器包装的原始类型的值
return value == ((Integer)obj).intValue();
}
return false;
}
现在应该一切都清晰了。