java自动装箱和自动拆箱学习小记

 

观察以下代码运行结果

Integer a = 1;
Integer b = 2;
Integer c = 3;
Integer d = 3;
 
Integer e = 321;
Integer f = 321;
 
Long g = 3L;
Long h = 2L;
 
System.out.println(c == d);//true
System.out.println(e == f);//false
System.out.println(c == (a + b));//true
System.out.println(c.equals((a+b)));//true
System.out.println(g == (a+b));//true
System.out.println(g.equals(a+b));//false
System.out.println(g.equals(a+h));//true

 

将以上代码进行反编译得到

 

 

分析:

第一个和第二个看下Integer的源码,里面有个本地缓存的使用,对于-128到127之间到数值会使用缓存里面的对象,

也就是说 Integer c = 3 或者 Integer c = Integer.valueOf(3) ,最终 c 得到的是Integer里的缓存对象  

同理,d也是获得该相同对象因此 进行 c == d 比较时,c和d引用的是同一个对象,因此就true  

而对于321,已经超出缓存范围了,因此 valueOf 方法会生成一个新的Integer对象因此e和f就引用不同 的对象了,进行==比较,当然就false了  

 

 

 

 

第三个由于a+b包含了算术运算,因此会触发自动拆箱过程(会调用intValue方法),==比较符又将左边的自动拆箱,因此它们比较的是数值是否相等。

第五个对于 g == (a+b),首先计算 a+b,也是先调用各自的intValue方法,得到数值之后,由于前面的g是Long类型的,也会自动拆箱为long,==运算符能将隐含的将小范围的数据类型转换为大范围的数据类型,也就是int会被转换成long类型,两个long类型的数值进行比较。

第六个对于 g.equals(a+b),同理a+b会先自动拆箱,然后将结果自动装箱,需要说明的是 equals 运算符不会进行类型转换。所以是Long.equals(Integer),结果当然是false

第七个对于g.equals(a+h),运算符+会进行类型转换,a+h各自拆箱之后是int+long,结果是long,然后long进行自动装箱为Long,两个Long进行equals判断。

牢记一句话:包装类在不遇到算数运算符的情况下不会触发自动拆箱,以及它们的equals()方法不处理数据类型的关系

posted @ 2019-12-11 22:12  电影公众号  阅读(248)  评论(0编辑  收藏  举报