简单案例
首先我们要理解Integer是int基本数据类型的封装类,也就是创建时应该是创建一个引用,并将引用指向这个对象。
当定义两个个Integer对象为-128到127中时,其实是不会创建新的引用的的,但是当超过这个范围后,就会创建一个新的引用,由于引用指向的地址都是不同的,所以两个比较的地址不同,所以返回结果自然是false。
源码如下:
private static classIntegerCache{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() {}
}
分析:我们可以看到从-128~127的数全部被自动加入到了包装类的对象池(也有称常量池)里面,意味着这个段的数使用的常量值的地址都是一样的。
原理如下:
1、== 这个运算在不出现算数运算符的情况下 不会自动拆箱,所以a1和 a2它们不是数值进行的比较,仍然是比较地址是否指向同一块内存。
2、它们都在包装类的对象池(也称常量池)中存储着。
3、编译阶段已经将代码转变成了调用valueOf方法,使用的是包装类的对象池(也有称常量池),如果超过了范围则创建新的对象。
复杂实例[-128~127]
Integer i1 = 40;
Integer i2 = 40;
Integer i3 = 0;
Integer i4 = new Integer(40);
Integer i5 = new Integer(40);
Integer i6 = new Integer(0);
System.out.println("i1=i2 " + (i1 == i2));
System.out.println("i1=i2+i3 " + (i1 == i2 + i3));
System.out.println("i1=i4 " + (i1 == i4));
System.out.println("i4=i5 " + (i4 == i5));
System.out.println("i4=i5+i6 " + (i4 == i5 + i6));
System.out.println("40=i5+i6 " + (40 == i5 + i6));----结果----(1)i1=i2 true
(2)i1=i2+i3 true
(3)i1=i4 false
(4)i4=i5 false
(5)i4=i5+i6 true
(6)40=i5+i6 true
注意点
1、当出现运算符的时候,Integer不可能直接用来运算,所以会进行一次拆箱成为基本数字进行比较
2、==这个符号,既可以比较普通基本类型,也可以比较内存地址看比较的是什么了
分析:
(1)号成立不用多说
(2)号成立是因为运算符自动拆箱
(3)(4)号是因为内存地址不同
(5)(6)号都是自动拆箱的结果
PS:equals方法比较的时候不会处理数据之间的转型,比如Double类型和Integer类型。
超过范围
假设一下,如果超出了这个范围之后呢?正如前文所言,所有的都将成为新的对象
Integer i1 = 400;
Integer i2 = 400;
Integer i3 = 0;
Integer i4 = new Integer(400);
Integer i5 = new Integer(400);
Integer i6 = new Integer(0);
System.out.println("i1=i2 " + (i1 == i2));
System.out.println("i1=i2+i3 " + (i1 == i2 + i3));
System.out.println("i1=i4 " + (i1 == i4));
System.out.println("i4=i5 " + (i4 == i5));
System.out.println("i4=i5+i6 " + (i4 == i5 + i6));
System.out.println("400=i5+i6 " + (400 == i5 + i6));
----结果----i1=i2 false
i1=i2+i3 true
i1=i4 false
i4=i5 false
i4=i5+i6 true400=i5+i6 true