由一个bug引出java包装类型

       工作中遇到过一个bug,用两个POJO的 Integer 字段 做 == 判断,明明“数值”相等结果返回 false。检查代码,调试,看源码搞了好久,才知道是Java包装类理解不够惹的祸。 

为了弄清楚其中的本质,先上一段代码:
 1         int a = 5;
 2         Integer b = 5;
 3         Integer c = Integer.valueOf(5);
 4         Integer d = Integer.valueOf(5);
 5         Integer e = new Integer(5);
 6         
 7         System.out.println("测试1,a == b 的结果:" + (a == b));
 8         System.out.println("测试2,b == c 的结果:" + (b == c));
 9         System.out.println("测试3,c == d 的结果:" + (c == d));
10         System.out.println("测试4,d == e 的结果:" + (d == e));
11         System.out.println("测试5,b == e 的结果:" + (b == e));
View Code

 

分析运行结果:测试1说明,一个“数值”与Integer 做==判断,Integer对象会进行自动拆箱然后再进行判断。测试2、3说明,b、c、d 这三个对象内存地址一样,其实是同一个对象。  测试4说明,b 与 e不是同一个对象,且两个 Integer 做 == 判断时不会进行自动拆箱操作。
进一步查看编译后的代码:
 发现 其实 b、c、d 都是通过 Integer.valueOf()方法创建的。a、b 比较时进行了拆箱操作。
更进一步查看Integer类的源代码:
 哦,原来是Integer内部维护一个对象池,默认值的范围 [-128,127]。(可以通过修改 -XX:AutoBoxCacheMax=<size> 设置缓存的大小,值的范围 [-128,x],low 参数不可修改)。
接来对比一下 new Integer()方法:
 直接创建,难怪b 与 e 不是同一个对象。
 
        Java 有八种基本类型,相应的就有八种包装类。既然Integer有缓存,那么其他类型有没有呢?还是来查看源码吧。(JDK版本 1.8.0_05)
 
Long:
 
Short:

 Byte:
 

 Float:
 
 
Double:
 
Boolean:
 
Character:
 
   Java的八个包装类,除Float,Double 外其他六个类都在内部维护一个对象池,像上面直接在代码中赋值,编译器后实际上是调用 valueOf(),先去缓存中查找,没有才会创建,减少对象的创建。包装类的对象与基本类型比较会自动拆箱,而对方也是同一个包装类的对象则和普通对象一样。
  分析这些有什么用呢?在Java中数据很多情况下用的是包装类型,当要进行比较时两方都是包装类,就会有可能得到诸如“为什么明明两个值一样就是不相等呢?”这样的结果。其他人怎么做我不知道,但是从上一次bug以后,代码中出现包装类比较,只要一方不是基本类型我就把包装拆箱。
 

转载于:https://www.cnblogs.com/chenzl1024/p/6780706.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值