Java 三目运算符表达式的一些问题

最近在处理一个需求,需求描述如下:对数据库中查询出来的数据的某一个字段做一个简单处理。处理方式是:如果该字段的值(取值范围0~4,有可能为null)等于0,那么默认处理成1。

测试代码如下:

 1 public class TestNull {
 2 
 3     private Integer starLevel;
 4 
 5     public Integer getStarLevel() {
 6         return starLevel;
 7     }
 8 
 9     public void setStarLevel(Integer starLevel) {
10         this.starLevel = starLevel;
11     }
12 
13     public static void main(String[] args) {
14         TestNull test = new TestNull();
15 
16         Integer localStartLevel =
17                 test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : test.getStarLevel();
18 
19         System.out.println(localStartLevel);
20     }
21 
22 }

因为不想写if-else,所以直接使用了三目运算符,原因嘛肯定是方便、简洁呀。一切都大功告成了,感觉自己棒棒哒!!!然后开始自测(发现代码没什么问题的童鞋不妨copy一下上面的代码执行一下),报错了!!!空!指!针!

老实说,当时我撸这段代码很自信,我调试这段代码也看了三遍才找到原因。如果你也没找到原因,你可以把那个1换成Integer.valueOf(1)或者将分号后面的test.getStarLevel()

直接换成null(当然这样是不符合需求的)再试试。

 

问题原因:可能你也发现问题所在了,就是因为那个“方便、简洁”的三目运算符表达式

分析原因:

1、test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : test.getStarLevel()

结论:错误!因为有个分支是返回基本类型数值1,另一个分支返回的直接是对象的调用值(该值的类型在运行时动态确定的),所以,三目运算符帮我们统一处理成了基本类型装箱操作。所以null装箱肯定空指针。

2、test.getStarLevel() != null && test.getStarLevel() == 0 ? Integer.valueOf(1) : test.getStarLevel();

 

结论:正确!因为基本类型1已经被初始化为Integer对象了,然后这个赋值表达式都是直接赋值引用了,所以不会存在问题。

 

3、test.getStarLevel() != null && test.getStarLevel() == 0 ? 1 : null

 

结论:正确!该段跟第一段代码的唯一区别就是test.getStarLevel()换成了null,这就消灭了运行时动态确定该分支的返回值类型的不确定性,所以能够正确执行。

 

 

三目运算符固然是好用,但是使用时还是需要注意返回值类型的统一性呀!且用且珍惜!

 

 

该博客仅代表个人观点,如有不足之处,请不吝惜指教!!!

 

Thanks!!!

posted @ 2017-08-01 18:17  Mr.Yanphet  阅读(1009)  评论(0编辑  收藏  举报