public class Test
{
public static void main(String[] args) throws Exception
{
Integer one = 100;
Integer two = 100;
Integer three = 200;
Integer four = 200;
int five = 100;
System.out.println(one == two);
System.out.println(five == two);
System.out.println(three == four);
}
}
结果是神马呢?
先不说结果,等分析就自然知道它的结果了。呵呵
先来看看它的字节码,看看它都做了些什么。
public static void main(java.lang.String[]) throws java.lang.Exception;
Exceptions:
throws java.lang.Exception Code:
Stack=3, Locals=6, Args_size=1
0: bipush 100 // 将常数100压栈
2: invokestatic #19; //Method java/lang/Integer.valueOf:(I)Ljava/lang/I
teger; // 调用Integer的valueOf方法
5: astore_1 // 将100赋给第一个变量
6: bipush 100 // 将常数100压栈
8: invokestatic #19; //Method java/lang/Integer.valueOf:(I)Ljava/lang/I
teger; // 调用Integer的valueOf方法
11: astore_2 // 将100赋给第一个变量
12: sipush 200
15: invokestatic #19; //Method java/lang/Integer.valueOf:(I)Ljava/lang/I
teger;
18: astore_3
19: sipush 200
22: invokestatic #19; //Method java/lang/Integer.valueOf:(I)Ljava/lang/I
teger;
25: astore 4
27: bipush 100
29: istore 5
31: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream;
34: aload_1
35: aload_2
36: if_acmpne 43
39: iconst_1
40: goto 44
43: iconst_0
44: invokevirtual #31; //Method java/io/PrintStream.println:(Z)V
47: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream;
50: iload 5
52: aload_2
53: invokevirtual #37; //Method java/lang/Integer.intValue:()I // 调用Integer的intValue方法
56: if_icmpne 63
59: iconst_1
60: goto 64
63: iconst_0
64: invokevirtual #31; //Method java/io/PrintStream.println:(Z)V
67: getstatic #25; //Field java/lang/System.out:Ljava/io/PrintStream;
70: aload_3
71: aload 4
73: if_acmpne 80
76: iconst_1
77: goto 81
80: iconst_0
81: invokevirtual #31; //Method java/io/PrintStream.println:(Z)V
84: return
看了字节码后,有点恍然大悟的感觉。
1、装箱
原来执行下面语句时
Integer one = 100;
调用了Integer的静态方法valueOf(这可能是编译器处理的)。
public static Integer valueOf(int i) {
final int offset = 128;
if (i >= -128 && i <= 127) { // must cache
return IntegerCache.cache[i + offset];
}
return new Integer(i);
}
此方法是JDK5.0之后才提供的,也就是所谓的“装箱”操作了。如果i的值在-128到127这个范围内,就会从“缓存”里面取它的值,如果超过这个范围的数,就直接返回i所代表的包装类。对-128到127这个范围内的数字进行缓存,可能是出于效率的考虑吧。
private static class IntegerCache {
private IntegerCache(){}
static final Integer cache[] = new Integer[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Integer(i - 128);
}
}
2、拆箱
System.out.println(five == two);
执行这句的时候,会把two转成原始int类型。调用Integer的实例方法intValue。
public int intValue() {
return value;
}
其中value是Integer的一个成员变量,
private final int value; |