专业编程基础技术教程

网站首页 > 基础教程 正文

享元模式的实例:Integer类

ccvgpt 2024-08-06 12:35:13 基础教程 13 ℃

享元模式的应用场景

运用共享技术有效地支持大量细粒度的对象。

  • 系统中存在大量相同或相似的对象,这些对象耗费大量的内存资源,利用共享技术避免创建大量重复对象,节省资源,提高性能。
  • 大部分的对象可以按照内部状态进行分组,且可将不同部分外部化,这样每一个组只需保存一个内部状态。
  • 使用享元模式需要维护一个存储享元对象的享元池,而这需要耗费资源,因此,应当在多次重复使用享元对象时才值得使用享元模式。

Integer实例

java语言的Integer就利用了享元思想,先来看看下面的代码输出结果。

享元模式的实例:Integer类

    public void testInteger() {
        Integer i = 7;
        Integer j = 7;
        Integer k = new Integer(7);
        Integer l = Integer.valueOf(7);
        Integer n = Integer.parseInt("7");
        Integer m = new Integer("7");
        System.out.println("i==j," + (i == j));
        System.out.println("i==k," + (i == k));
        System.out.println("i==l," + (i == l));
        System.out.println("i==n," + (i == n));
        System.out.println("i==m," + (i == m));

        Integer x = 1000;
        Integer y = 1000;
        Integer z = Integer.valueOf(1000);
        System.out.println("x==y," + (x == y));
        System.out.println("x==z," + (x == z));
    }

输出结果:

i==j,true
i==k,false
i==l,true
i==n,true
i==m,false
x==y,false
x==z,false

从上面的代码运行输出结果可以看出,相同值7的Integer对象可以是同一个对象,而如果都为1000则不是同一个对象。

java.lang.Integer源码

public final class Integer extends Number implements Comparable<Integer> {

    private final int value;
    
    public Integer(int value) {
        this.value = value;
    }
    /**
     * 内部缓存类
     */
    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
        static {
            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);
                    h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                }
            }
            high = h;
            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;
        }
        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);
    }
    
    
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
}

看上面的代码我们可以发现:

  1. Integer的equals方法,比较的是对象的int值
  2. Integer的valueOf()方法,使用的享元模式,对取值范围-128到127的值进行缓存,不再构造相同的对象,并且缓存数据的默认最大值是127,还可以通过java.lang.Integer.IntegerCache.high进行自定义,最大可以达到Integer.MAX_VALUE - 129
  3. 利用new Integer()构造出的对象,没有使用到缓存的对象,利用==比较,都不会相同。
  4. 装箱过程就是通过Integer类的 valueOf() 方法实现的,而拆箱过程是通过调用intValue() 方法实现。

小结

虽然java语言的Integer类不是标准的享元模式,但是其实现思想和利用静态内部类来实现缓存的思路值得我们借鉴。

最近发表
标签列表