基本类型对应的包装类

clipboard2.png

Integer,Short,Long,Byte,Float,Double都是Number的子类.

Character和Boolean为Object的直接子类.


基本类型与包装类在内存中的区别

int a=10; //作为局部变量
在栈中存储名为a,值为10的变量.与堆内存无关.

int a=10; //作为属性
在存储在堆的对象中存储名为a,值为10的属性

Integer a = new Integer(10)
在堆中创建一个Integer对象,其value值为10,然后在栈/堆的对象中存储名为a,值为上述对象地址的变量/属性.


与字符串之间的转换

clipboard.jpg


包装类的缓存处理

背景:包装类在使用时是在堆中创建了一个对象,频繁创建对象会浪费很大的开销,增加GC,为了提高效率,在Byte,Character,Integer,Short,Long中建立缓存.
(注意:不包含浮点型的Float和Double)

以Integer为例

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

IntegerCache是Integer中的一个静态内部类,缓存由该内部类建立.缓存实质上是一个Integer数组.其下限值固定为-128,上限值由代码确定,默认上限值为127,即缓存-128至127的Integer对象.IDEA中可以在运行之前通过编辑配置(Edit Configuration)-VM选项(VM options),-XX:AutoBoxCacheMax=1000来设定缓存上限.

具体的使用如下,以valueOf方法为例

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

如果int数据在缓存范围之内,则直接返回加载Integer类时建立的缓存中的对象.如果不在范围内则单独创建.

面试题:

        Integer i1 = 100;
        Integer i2 = 100;
        System.out.println(i1 == i2); //true
        System.out.println(i1.equals(i2)); //true

        Integer i3 = 10000;
        Integer i4 = 10000;
        System.out.println(i3 == i4); //false
        System.out.println(i3.equals(i4)); //false

同样的

Byte的缓存范围为-128至127,即Byte的整个取值范围都在缓存之内.

Short和Long的缓存范围为-128至127,但是无法由用户自行设置上限值.

Character的缓存范围为0-128的字符

但是缓存处理只在调用valueOf()时起作用.如果对象是通过new或者反射产生的,那么建立的缓存不起作用.


Severus
10 声望0 粉丝

下一篇 »
JavaSE IO总结