踩了一个java中三目运算符的坑

        前两天在开发中遇到了一个很诡异的NPE情况,最后发现是三目运算符的编译问题,这里记录一下。

        简化后的代码如下:

Map<String, Long> map = Maps.newHashMap();
map.put("a", 123L);
TmpCls cls = new TmpCls();
cls.setPrice(ObjectUtils.isEmpty(map) ? 0L : map.get("b"));

        原代码的map其实是从数据库查出的结果,如果没查到数据,price就是0,否则就取查到的数据,有时就会出现上面例子的情况,map.get()取不到数据。

        从代码本身来看,是没任何问题的,但是遇到这种取不到的情况,就会报一个NPE,百思不得其解。最后看了一下反编译的结果,才发现其中原因。

        反编译以后,最后的那个三目运算符的代码是这样的

cls.setPrice(ObjectUtils.isEmpty((Object)map) ? 0L : ((long)map.get("b"));

        会发现,它会将map.get()方法外包进行了long型强转,如果这里没有获取到信息,那么就是null了。

        具体原因还真不清楚,大概猜想,应该是编译器根据目标类型进行了推导的结果。

        解决的办法有三种:

        1、不使用三目运算符,这个比较简单,就不说明了

        2、对原数据进行判空操作,可以使用Optional进行简单包装。

cls.setPrice(ObjectUtils.isEmpty(map) ? 0L : Optional.ofNullable(map.get("b")).orElse(0L));

        3、将后面的逻辑移到外面先做处理,不过这里也有一个小问题。

long l=ObjectUtils.isEmpty(map) ? 0L : map.get("b");//NPE
Long l=ObjectUtils.isEmpty(map) ? 0L : map.get("b");//正常

        我也是通过这个测试,才推断应该是编译器进行了类型推导的。

        另外还需要说一下,我用eclipse和idea都进行了这个测试,发现在eclipse中,第三种解决办法里,即使使用包装类型,也依然会有NPE产生,这个应该是IDE的问题吧,因为我查了一下用的都是自己安装的JDK8。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值