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!!!