场景
java开发手册中对于三目运算符的使用要求如下:
【强制】三目运算符 condition? 表达式 1 : 表达式 2 中,高度注意表达式 1 和 2 在类型对齐时,
可能抛出因自动拆箱导致的 NPE 异常。
说明:以下两种场景会触发类型对齐的拆箱操作:
1) 表达式 1 或表达式 2 的值只要有一个是原始类型。
2) 表达式 1 或表达式 2 的值的类型不一致,会强制拆箱升级成表示范围更大的那个类型。
下面看一个反例:
Integer a = 1;
Integer b = 2;
Integer c = null;
Boolean flag = false;
Integer result = (flag?a*b:c);
上面写法会触发NullPointException-a*b的结果是int类型,那么c会强制拆箱成Int类型,抛出异常。
注意:
对于条件表达式b?x:y,先计算条件 b,然后进行判断。如果 b 的值为 true,
计算 x 的值,运算结果为 x 的值;否则,计算 y 的值,运算结果为 y 的值。
一个条件表达式从不会既计算 x,又计算 y。
条件运算符是右结合的,也就是说,从右向左分组计算。例如,a?b:c?d:e 将按 a?b:(c?d:e)执行。
根据规定,三目运算符的第二、第三位操作数的返回值类型应该是一样的,这样才能当把一个三目运算符的结果赋值给一个变量。
如:Person i = a>b : i1:i2; ,就要求 i1 和 i2 的类型都必须是 Person才行。因为 Java 中存在一种特殊的情况,
那就是基本数据类型和包装数据类型可以通过自动拆装箱的方式互相转换。即可以定义 int i = new Integer(10);也可以定义Integer i= 10;
那如果,三目运算符的第二位和第三位的操作数的类型分别是基本数据类型和包装类型对象时,就需要有一方需要进行自动拆装箱。
根据三目运算符的语法规范,当第二,第三位操作数分别为基本类型和对象时,其中的对象就会拆箱为基本类型进行操作。
下面再看一个反例
boolean b1 = true;
boolean b2 = false;
Boolean nullBool = null;
boolean result = b1 ? nullBool : b2;