Integer自动装箱“陷阱”

1、基本数据类型所对应的包装类

byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean

2、数据的装箱与拆箱

拆箱:将包装类型数据转换成基本类型数据

装箱:将基本类型数据包装成包装类型数据

装箱和拆箱的方法:

​ 装箱:使用包装类中的构造方法,或静态valueOf方法

int a = 5;
Integer i = new Integer(a);

拆箱:使用包装类的xxxValue方法

Integer i = new Integer(5);
int a = i.intValue();

JDK1.5以后,新增了自动装箱和自动拆箱功能

自动装箱:可以直接将基本类型数据赋值给包装类对象

int a = 5;
Integer i = a;// Integer.valueOf(a);

自动拆箱:可以直接向包装类对象数据赋值给基本类型变量

Integer in i = new Integer(5);
int a = i;//i.intVaule();

3、Integer自动装箱的"陷阱"

​
//自动装箱
//Integer integer1 = 100;
Integer integer1 = Integer.valueOf(100);
//Integer integer2 = 100;
Integer integer2 = Integer.valueOf(100);
System.out.println("integer1==integer2\t"+(integer1==integer2));

Integer integer3 = new Integer(128);
Integer integer4 = new Integer(128);
System.out.println("integer3==integer4\t"+(integer3==integer4);

​

输出结果:

integer1==integer2    true
integer3==integer4    false

上面的结果应该会出乎不少人的意料吧

因为我们大家如果有些java基础的话,都应该清楚“==”对于对象的比较,比较的并不是对象的值,而是对象的地址。

既然比较的是地址,那么大家或许会有疑问了,第一对比较,integer1 和 integer2是两个不同的包装对象,比较结果不应该是false吗??? 为何会是true.

我们可以观察一下源码

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 =
                sun.misc.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() {}
    }

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

我们可以看到valueOf方法对int类型装箱之前有一个判断,当int的值在-128~127范围之外的时候才会通过new关键字实例化对象返回,否则的话返回的是缓存区中的值。

看到这里,我们应该可以明白为什么第一对比较的结果为true了吧。

因为100在-128~127之间,缓存区存在值,integet1和integer2都指向缓存区中的值,所以其地址是相同,便返回true.

简单画的草图,帮助理解。

猜你喜欢

转载自blog.csdn.net/qq_36418435/article/details/81511209