享元模式-integer

一.integer包装类

先看个小例子

        Integer i1 = 25;
        Integer i2 = 25;
        Integer i21 = Integer.valueOf(25);
        Integer i22 = new Integer(25);
        Integer i3 = 128;
        Integer i4 = 128;
        System.out.println(i1 == i2);   //true
        System.out.println(i1 == i21);  //true
        System.out.println(i1 == i22);  //false
        System.out.println(i3 == i4);   //false

看到结果,why?我们知道==比较是否指向相同的对象,本质是栈内局部变量表中reference存储的值是否相等,对于基本类型存储的是数据值,对于引用类型(接口,类,数组)存储的是堆中对象的地址。
1.Integer i22 = new Integer(25); 毫无疑问是在堆中创建一个新对象;
2.Integer i1 = 25;我们知道会触发自动装箱操作,也就是调用valueOf()来创建Integer 对象,为何相同呢?因为在类加载时内部类IntegerCache中的静态块已经把部分(默认是-128~127)Integer对象初始化好缓存起来了static final Integer cache[];

    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");  --可配置
...
public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }

so,Integer i1 = 25; 和 Integer.valueOf(25);直接来这个cache[]读取共享复用就行了。

  1. Integer i3 = 128; Integer i4 = 128; 超出了high位,需要自行创建新对象。

二. String享元模式和包装类型区别

Integer 类中要共享的对象,是在类加载的时候,就集中一次性创建好的。
但是,对于字符串来说,我们没法事先知道要共享哪些字符串常量,所以没办法事先创建好,只能在某个字符串常量第一次被用到的时候,存储到常量池中,当之后再用到的时候,直接引用常量池中已经存在的即可,就不需要再重新创建了。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容