美文网首页
为什么 100 == 100, 200 != 200

为什么 100 == 100, 200 != 200

作者: ddu_ | 来源:发表于2018-09-04 23:19 被阅读14次

    这是道蛮有意思的面试题。
    不废话,看题:

    public class Main {
        public static void main(String[] args) {
    
            Integer i1 = 100;
            Integer i2 = 100;
            Integer i3 = 200;
            Integer i4 = 200;
    
            System.out.println(i1 == i2); 
            System.out.println(i3 == i4); 
        }
    }
    

    输出是多少?

    运行下试试:

    运行结果

    这是道极好的考察基础的面试题。如果我是面试官,我并不 care 你能不能答对。接下来我会问下面两个知识点

    • == 和 equals 的区别
    • Integer 自动装箱过程

    == 和 equals 的区别

    这个问题都问烂了,简单说一下。
    ==:判断是否是同一个引用,或两个基本类型是否相等
    equals:类覆写的一个方法,用于判断两个对象是否 equal,判断规则由覆写的方法决定

    Integer 自动装箱过程

    整型自动装箱会调用 Integer 的 valueof 方法,返回一个 Integer 对象,该方法有多个重载。

    //Interger 的 valueof 方法
    public static Integer valueOf(String s, int radix) throws NumberFormatException {
            return Integer.valueOf(parseInt(s,radix));
    }
    
    public static Integer valueOf(String s) throws NumberFormatException {
            return Integer.valueOf(parseInt(s, 10));
    }
    
    public static Integer valueOf(int i) {
            if (i >= IntegerCache.low && i <= IntegerCache.high)
                return IntegerCache.cache[i + (-IntegerCache.low)];
            return new Integer(i);
    }
    

    这里就可以解释下为什么 “200 != 200” 了。

    Integer i3 = 200; -> Integer.valueof(200)

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

    看看 IntegerCache

    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");
                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.low 到 IntegerCache.high 之间的数做了缓存,在这个区间的数的包装类型始终是同一个引用,不在这个区间就会重新分配内存。所有 i1 == i2, i3 != i4。

    jdk 这么做,我猜应该是这些较小的数,通常情况下使用比较频繁,干脆缓存起来,免得反复分配回收内存。

    相关文章

      网友评论

          本文标题:为什么 100 == 100, 200 != 200

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