美文网首页Android基础Java 基础
Java 常用类 03. Java 整数缓冲区

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

作者: yjtuuige | 来源:发表于2021-12-16 14:51 被阅读0次

    问题:

    • 同样为数字 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 整数缓冲区

        本文链接:https://www.haomeiwen.com/subject/bpiefrtx.html