java入门包装类-Integer

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方法比较的是对象的值,而非引用传递的值

猜你喜欢

转载自blog.csdn.net/makeliwei1/article/details/78180530