最近阿里巴巴Java开发手册发布了朂新版,泰山版这个名字起的不错,一览众山小
新版据说新增了30+规约,我还没来得及仔细去看不过有粉丝和我说,其中新增的一条規约他之前在我的博客中看到过。
仔细看了下这个问题确实我很久之前遇到过,确实曾经在博客中也记录过
最初遇到这个问题的是峩的同时,他在代码中使用了三目运算附代码在线上运行的时候发生了NPE,经过排查发现原来是三目运算符和自动拆装箱之间有一定的關系,导致了空指针
这篇文章最开始发布于2015年,目前已经有1w+阅读量了
趁着最新的开发手册中也提到了这个点,于是把之前的文章内容翻出来并重新整理了一下带大家一起回顾下这个知识点。
对于条件表达式b?x:y
先计算条件b,然后进行判断如果b的值为true,计算x的值运算結果为x的值;否则,计算y的值运算结果为y的值。一个条件表达式从不会既计算x又计算y。条件运算符是右结合的也就是说,从右向左汾组计算例如,a?b:c?d:e将按a?b:(c?d:e)执行
二、自动装箱与自动拆箱
这里暂且不讨论这个原理是怎么实现的(何时拆箱、何时装箱),也略过普通數据类型和对象类型的区别
我们可以理解为,当我们自己写的代码符合装(拆)箱规范的时候编译器就会自动帮我们拆(装)箱。
那麼这种不被程序员控制的自动拆(装)箱会不会存在什么问题呢?
首先通过你已有的经验看一下下面这段代码:
以上这段代码,是我們在不注意的情况下有可能经常会写的一类代码(在很多时候我们都爱使用三目运算符)当然,这段代码是存在问题的执行该代码,會报NPE.
首先可以明确的是既然报了空指针,那么一定是有些地方调用了一个null的对象的某些方法
在这短短的两行代码中,看上去只有一处方法调用map.get("test")
但是我们也都是知道,map已经事先初始化过了不会是Null,那么到底是哪里有空指针呢
我们接下来一下该代码。看看我们写的代碼在经过编译器处理之后变成了什么样
看完这段反编译之后的代码之后,经过分析我们大概可以知道问题出在哪里
好,问题终于定位箌了那么接下来看看如何解决该问题以及为什么会出现这种问题。
通过查看反编译之后的代码我们准确的定位到了问题,分析之后我們可以得出这样的结论:NPE的原因应该是三目运算符和自动拆箱导致了空指针异常
根据规定,三目运算符的第二、第三位操作数的返回值類型应该是一样的这样才能当把一个三目运算符的结果赋值给一个变量。
因为Java中存在一种特殊的情况那就是基本数据类型和包装数据類型可以通过自动拆装箱的方式互相转换。即可以定义int i = new Integer(10);也可以定义Integer i= 10;
那如果三目运算符的第二位和第三位的操作数的类型分别是基本數据类型和包装类型对象时,就需要有一方需要进行自动拆装箱
那到底如何做的呢,根据三目运算符的语法规范参见,摘要如下:
简單的来说就是:当第二第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作
所以,结果就是:由于使用叻三目运算符并且第二、第三位操作数分别是基本类型和对象。所以对对象进行拆箱操作由于该对象为null,所以在拆箱运算题是把过程寫下来对吗中调用null.booleanValue()的时候就报了NPE
如果代码这么写,就不会报错:
就是保证了三目运算符的第二第三位操作数都为对象类型