自动装箱拆箱

1、简介

装箱:自动把基本类型转化为包装器类型

拆箱:自动把包装器类型转化为基本类型

2、主要对应的包装器类型

byte       (1字节)      Byte

short      (2字节)      Short

int          (4字节)      Integer

long       (8字节)      Long

float       (4字节)      Float

double   (8字节)      Double

char       (2字节)      Char

boolean    ()            Boolean

3、实现

        以Integer为例:装箱的时候自动调用的是Integer的valueOf(int)方法。拆箱的时候自动调用的是Integer的intValue方法,其他类似。

       Integer、Short、Byte、Character、Long这几个类的valueOf方法的实现是类似的。例如Short,如果在-128到127之间,会走ShortCache,超过这个范围会new对象。所以做比较时,在-128到127之间可以用“==”,超过这个范围需要用equals,否则返回false。

    public static Short valueOf(short s) {
        final int offset = 128;
        int sAsInt = s;
        if (sAsInt >= -128 && sAsInt <= 127) { // must cache
            return ShortCache.cache[sAsInt + offset];
        }
        return new Short(s);
    }

        Double、Float的valueOf方法的实现是类似的,例如Double,调用的valueOf(String s):

    public static Double valueOf(String s) throws NumberFormatException {
        return new Double(FloatingDecimal.readJavaFormatString(s).doubleValue());
    }

    public static Double valueOf(double d) {
        return new Double(d);
    }

4、缓存数据

        Integer、Short、Byte、Character、Long这几个类中都有个内部缓存类,Double、Float的类中没有。

        Byte,Short,Long 有固定范围: -128 到 127。对于 Character, 范围是 0 到 127。除了 Integer 可以通过参数改变范围外,其它的都不行

        以Integer为例,缓存类IntegerCache,缓存了-127到128的数据,不管创建多少个这个范围内的Integer用ValueOf出来的都是同一个对象,减少了new的时间也就提升了效率。同时JDK还提供cache中high值得可配置。

        Short、Byte、Character、Long类中也实现了类似的缓存类,但是没有提供high值的配置。

    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) {
                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);
            }
            high = h;

            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
        }

        private IntegerCache() {}
    }

5、==和equals

   ==基本数据类型比较内容,实质也是比较地址(因为对于基本类型来说,当值相同的时候,地址也是相同的),对象比较比较地址。对于java中的“==”操作符号,jvm会根据两边互相比较的操作数的数据类型,来调用不同的指令。对于于boolean,byte、short、int、long这种整形操作数会生成 if_icmpne指令,该指令用于比较整形数值是否相等。如果操作数是对象的话,编译器则会生成if_acmpne指令,与if_icmpne相比将i(int)改成了a(object reference)。

   equals是Object类中的方法,所有继承Object的类都有此方法。Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。像String中的equals都是对这个方法的重写,比较的是所指向的对象的内容。

6、面试常问的一个问题:

Integer i = new Integer("123")和Integer i = 123;这两种方式的区别

答:第一种方式不会触发自动装箱的过程,直接new对象;而第二种方式会触发装箱过程;

 



猜你喜欢

转载自blog.csdn.net/yanweihpu/article/details/80164000