先看下面三组比较
public static void main(String[] args) {
Integer i1 = 100;
Integer i2 = 100;
System.out.println(i1 == i2);
Integer i3 = 200;
Integer i4 = 200;
System.out.println(i3 == i4);
Integer i5 = 200;
int i6 = 200;
System.out.println(i5 == i6);
}
结果:
true
false
true
通过把上述源码转成字节码文件分析下问什么是产生上面的结果
先看第一组
0: bipush 100
2: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: bipush 100
8: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: astore_2
12: getstatic #22 // Field java/lang/System.out:Ljava/io/PrintStream;
15: aload_1
16: aload_2
17: if_acmpne 24
20: iconst_1
21: goto 25
24: iconst_0
25: invokevirtual #28 // Method java/io/PrintStream.println:(Z)V
通过第一组生成的字节码可以看出,关键地方还在于java/lang/Integer.valueOf,看看java/lang/Integer.valueOf源码是如何处理的:
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache[];
static {
// high value may be configured by property
int h = 127;
String integerCacheHighPropValue =
VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if (integerCacheHighPropValue != null) {
try {
int i = parseInt(integerCacheHighPropValue);
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
} catch( NumberFormatException nfe) {
// If the property cannot be parsed into an int, ignore it.
}
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
// range [-128, 127] must be interned (JLS7 5.1.7)
assert IntegerCache.high >= 127;
}
private IntegerCache() {}
}
通过上面源码可以看出,java/lang/Integer.valueOf在输入的int在﹣128与﹢127之间返回的是IntegerCache中已缓存的对象,所以Integer i1 = 100;Integer i2 = 100;其实是一个对象,结果是true.
再看第二组
明白了第一组其实第二个很好理解,200并没有再IntegerCache中,所有返回的是2个新的对象,2个不同的对象相比返回false.
看最后一组
为什么对象与基本数据类型就相等?
60: sipush 200
63: invokestatic #16 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
66: astore 5
68: sipush 200
71: istore 6
73: getstatic #22 // Field java/lang/System.out:Ljava/io/PrintStream;
76: aload 5
78: invokevirtual #34 // Method java/lang/Integer.intValue:()I
81: iload 6
83: if_icmpne 90
86: iconst_1
87: goto 91
90: iconst_0
91: invokevirtual #28 // Method java/io/PrintStream.println:(Z)V
关键在于ava/lang/Integer.intValue:()I:
private final int value;
public int intValue() {
return value;
}
Java的自动拆箱,对象最后返回的是int的基本类型,2个基本类型的int对比,200==200,所有返回的是true.