美文网首页Java 杂谈未分类程序员
java自动装箱拆箱语法糖是如何工作的?

java自动装箱拆箱语法糖是如何工作的?

作者: alonwang | 来源:发表于2018-10-11 09:52 被阅读4次

    基本类型和包装类型的自动装箱拆箱原理并不复杂,但是在日常使用中频率极高,如果不理解语法糖背后的奥秘,很可能陷入误区而不自知,下面以一个例子说明这个语法糖的工作原理

    这个例子摘自深入理解java虚拟机第二版(强烈推荐阅读)

        public static void main(String[] args) {
            //part1
            Integer a = 1;
            Integer b = 2;
            Integer c = 3;
            Integer d = 3;
            Integer e = 321;
            Integer f = 321;
            Long g = 3L;
            //part2
            System.out.println(c == d);//1
            System.out.println(e == f);//2
            System.out.println(c == (a + b));//3
            System.out.println(c.equals(a + b));//4
            System.out.println(g == (a + b));//5
            System.out.println(g.equals(a + b));//6
        }
    

    猜测结果前需要说明以下几个基本原则

    1. 包装类的==运算在不遇到算数运算的情况下不会自动拆箱
    2. 包装类型存在缓存,如Integer在-128~127是有缓存的,具体参见8大基本类型的包装类型缓存探究
    3. 包装类型的equals不处理转型问题
    4. 包装类型遇到算数运算时会进行自动拆箱
    5. 基本类型在需要包装类型时会进行自动装箱

    结果如下

    true//1
    false//2
    true//3
    true//4
    true//5
    false//6
    

    下面结合反编译出的代码分析

        public static void main(String[] args) {
            //part1
            Integer a = Integer.valueOf(1);
            Integer b = Integer.valueOf(2);
            Integer c = Integer.valueOf(3);
            Integer d = Integer.valueOf(3);
            Integer e = Integer.valueOf(321);
            Integer f = Integer.valueOf(321);
            Long g = Long.valueOf(3L);
            //part2
            System.out.println(c == d);//1
            System.out.println(e == f);//2
            System.out.println(c.intValue() == a.intValue() + b.intValue());//3
            System.out.println(c.equals(Integer.valueOf(a.intValue() + b.intValue())));//4
            System.out.println(g.longValue() == a.intValue() + b.intValue());//5
            System.out.println(g.equals(Integer.valueOf(a.intValue() + b.intValue())));//6
        }
    

    观察原代码和反编译后代码可以看出

    • part1 定义a~f时发生了自动装箱,并且使用了缓存(Integer.valueOf())
    • part2 在进行==比较时发生了自动拆箱(Integer.intValue())

    对于语句进行分析

    1. c==d 对于对象==比较的是他们的内存地址,由于c,d都是从Integer的缓存中获取的,是同一个对象,因此结果是true
    2. e==f 与上面相同,但是321已经不在缓存范围内,因此结果是false
    3. c=a+b 发生自动拆箱,进行基本类型的==比较,3=1+2,结果为true
    4. c.equals(a+b) 首先由规则4,a+b进行自动拆箱,然后由于规则5,equals需要包装类型,进行自动装箱且带有缓存,得到对象Integer(3),它和c都是从缓存时获取的,因此结果true
    5. g==a+b a+b发生自动拆箱,而后类型提升为long,因此结果为true
    6. g.equals(a+b) 由规则3,最终比较时为Long.equals(Integer),类型都不同,结果当然为false

    相关文章

      网友评论

        本文标题:java自动装箱拆箱语法糖是如何工作的?

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