Java 常用类 03. Java 整数缓冲区

问题:

  • 同样为数字 100 为什么结果有时返回 false,有时返回 true,而用同样的方法再使用 200,却带来不同的结果。具体看代码及运行结果。
public class Main {
    public static void main(String[] args) {
        Integer n1=new Integer(100);
        Integer n2=new Integer(100);
        System.out.println(n1==n2);
        Integer n3=100;    // 自动装箱
        Integer n4=100;
        System.out.println(n3==n4);
        Integer n5=200;    // 自动装箱
        Integer n6=200;
        System.out.println(n5==n6);
    }
}
  • 结果:

原因:

  • Java 预先创建了 256 个常用的整数包装类型对象。(类似字符串中的字符串池,只是这个池中已经有内容了)
  • 在实际应用当中,对已创建的对象进行复用。
  • 缓存区数组 [-128, 127]

分析:

  • n1、n2 比较:属于两个对象,存储的地址不同,所以不相等返回 false。
  • n3、n4 和 n5、n6 通过自动装箱创建,但比较结果不同
  • 上面的代码可以写成:
public class Main {
    public static void main(String[] args) {
        Integer n1=new Integer(100);
        Integer n2=new Integer(100);
        System.out.println(n1==n2);
        // 自动装箱,Integer.valueOf() 为隐藏代码
        Integer n3=Integer.valueOf(100);
        Integer n4=Integer.valueOf(100);
        System.out.println(n3==n4);
        // 自动装箱,Integer.valueOf() 为隐藏代码
        Integer n5=Integer.valueOf(200);
        Integer n6=Integer.valueOf(200);
        System.out.println(n5==n6);
    }
}
  • 查看 valueOf() 源码:
@IntrinsicCandidate
    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 i) 方法中的参数值在 IntegerCache.lowIntegerCache.high 之间时,会返回数组 IntegerCache.cache[] 中的值。
  • 查看 IntegerCache 类的源码:
private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer[] cache;
        static Integer[] archivedCache;

        static {
            // high value may be configured by property
            int h = 127;
            String integerCacheHighPropValue =
                VM.getSavedProperty("java.lang.Integer.IntegerCache.high");
            if (integerCacheHighPropValue != null) {
                try {
                    h = Math.max(parseInt(integerCacheHighPropValue), 127);
                    // Maximum array size is Integer.MAX_VALUE
                    h = Math.min(h, Integer.MAX_VALUE - (-low) -1);
                } catch( NumberFormatException nfe) {
                    // If the property cannot be parsed into an int, ignore it.
                }
            }
            high = h;

            // Load IntegerCache.archivedCache from archive, if possible
            CDS.initializeFromArchive(IntegerCache.class);
            int size = (high - low) + 1;

            // Use the archived cache if it exists and is large enough
            if (archivedCache == null || size > archivedCache.length) {
                Integer[] c = new Integer[size];
                int j = low;
                for(int i = 0; i < c.length; i++) {
                    c[i] = new Integer(j++);
                }
                archivedCache = c;
            }
            cache = archivedCache;
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }

        private IntegerCache() {}
    }
  • 从源码中可以看出 IntegerCache.low==-128IntegerCache.high==127,同时可以看出,数组 cache[]大小为 256,存放的元素为 {-128,-127,…,126,127}
  • 因为 100 在 IntegerCache.low~IntegerCache.high 之间,所以返回的是数组 cache[] 中的元素,所以在比较 n3 与 n4 时,两者指向的为同一元素,同一地址,而 200 并不在上面的范围中,所以返回 new Interger(200)
  • 相当于
public class Main{
    public static void main(String[] args) {
        Integer a[]={100};
        Integer n3=a[0];
        Integer n4=a[0];
        System.out.println(n3==n4);
        Integer n5=new Integer(200);
        Integer n6=new Integer(200);
        System.out.println(n5==n6);
    }
}

你可能感兴趣的:(Java 常用类 03. Java 整数缓冲区)