自动装箱拆箱本质

作者: 隔壁老王的隔壁啊 | 来源:发表于2017-12-12 18:34 被阅读49次

    前言

    在讲自动转拆箱之前,我先出一个题目吧,如果能够答对并且知道为什么,那么久不用看本篇了。

    public static void main(String[] args) {
        Integer i = 128 ; // 装箱
        Integer j = 128 ;
        Integer x = 1 ; // 装箱
        Integer y = 1 ;
        
        System.out.println(i == j); // false
        System.out.println(x == y); // true 
    }
    

    其实在我们学习java基础的时候学过装箱拆箱的概念,可能你当时只是理解为Integer和int能够自动转换,而并没有深究是怎么实现的。OK,只好查看源码了。

    分析

    List<Integer> list = new ArrayList<Integer>();
    list.add(1);
    

    如果你在第二行代码debug的话,肯定会进入到。

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

    从上面可以知道

    如果i的值在-128~127之间,则从缓存中取,否则直接创建一个Integer对象.

    我们再来看看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() {}
        }
    

    上面代码在static块里。

    现在可以解释前言中的问题了,如果一个值在-128~127之中,则会直接在缓存中取,否则会直接创建一个Integer对象。所以上面i == j 为false。

    总结

    有些东西看着很简单,但是容易掉坑哦~~~

    欢迎关注公众号


    架构师之途

    相关文章

      网友评论

        本文标题:自动装箱拆箱本质

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