package day10_9;
public class IntegerDemo {
public static void main(String[] args) {
Integer i3 = 100;
Integer i4 = 100;
System.out.println(i3==i4);
Integer i5 =1000;
Integer i6 =1000;
System.out.println(i5 == i6);
}
}
以上代码运行结果为:
true
false
对于上面的结果是比较意外的,对于以上java文件编译生成的class文件进行反编译得到以下代码
public class IntegerDemo {
public static void main(String[] args) {
Integer i3 = Integer.valueOf(100);
Integer i4 = Integer.valueOf(100);
System.out.println(i3==i4);
Integer i5 =Integer.valueOf(1000);
Integer i6 =Integer.valueOf(1000);
System.out.println(i5 == i6);
}
}
这里我们可以看到对于Integer的对象在初始化时会调用Integer的valueOf方法。那么valueOf方法是如何实现的,我们先看看下面的代码
public static Integer valueOf(int i) {
if(i>= IntegerCache.Low && i<=IntegerCache.high) {
return IntegerCache.cache[i+(-IntegerCache.Low)];
return new Interger(i);
}
}
我们可以看到,如果我们初始化的值i在IntegerCache.Low和IntegerCache.high之间的话,此时返回的是一IntegerCache方法中cache数组中的已有的数值,如果初始化的值不在IntegerCache.Low和IntegerCache.high中的话,那么就会在堆内存中开辟新的内存,而此时i5或者i6指向的就是新开辟内存的地址。现在我们看看IntegerCache方法
private static class IntergerCache{
static final int Low = -128;
static final int high;
static final Integer cache[];
/*static {
int h = 127;
String integerCacheHighProValue = sun.misc.VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
if(integerCacheHighProperty != null) {
try {
int i = parseInt(integerCacheHighProperty);
i = Math.max(i, 127);
h = Math.min(i, Integer.MAX_VALUE-(-Low)-1);
}
catch(NumberFormatException nfe) {
}
}*/这一块代码表示很明白
cache = new Integer[(high-Low)+1];
int j = Low;
for(int k = 0;k<cache.length;k++) {
cache[k] = new Integer(j++);
}
assert IntegerCache.high>=127;
}
}
根据知乎的清浅池塘的理解就是当我们初始化的值在-128到127之间,如果第一个对象如i3的初始化为100,i4此时的初始化也为100,因此,i4这个 对象就不会新开辟一个内存空间,这样一来,i3和i4指向的就是同一个内存地址,因此在用i3==i4比较时返回的是true,而i5和i6因为初始化值超过了127,因此属于i5和i6的指向的内存地址是不一样的。
再看下面的代码
public class IntegerDemo {
public static void main(String[] args) {
Integer i3 = 100;
Integer i4 = 100;
System.out.println(i3.equals(i4));
Integer i5 =100000000;
Integer i6 =100000000;
System.out.println(i5.equals( i6));
}
}
我们这里使用的是equals(object obj)方法,此时比较的就是两个对象存储的值是否相同。在Integer类中的equals方法如下:
public boolean equals(Object obj){
if(obj instanceOf Integer){
return value == ((Integer)obj).intValue();
}
return false;
}
从上面我们可以看到Integer的equals方法比较的是对象的值,而非引用传递的值