我试图理解下面的代码。第 2 行输出null,而第 3 行抛出NullPointerException。我缺少什么?理论上它应该有效。public static void main(String []args){ 1 Object[] obj = {null}; 2 System.out.println((Integer)obj[0]); //Output null 3 Integer n = obj[0] == null ? (Integer)obj[0] : 1; //NullPointerException 4 System.out.println(n); }
2 回答
小唯快跑啊
TA贡献1863条经验 获得超2个赞
根据JLS中定义的规则,三元条件运算符的类型
null ? (Integer)obj[0] : 1;
是int
, 不是Integer
.
因此,当该表达式的结果为 时(Integer)obj[0]
,将Integer
拆箱为int
,得到NullPointerException
。
参见JLS 15.25。条件运算符 ? :,表 15.25-A。:
由于第二个操作数是Integer
,第三个操作数是int
,因此条件表达式类型是int
。
Helenr
TA贡献1780条经验 获得超4个赞
这里的关键概念是二进制数字提升。
当您为运算符提供不同类型的操作数时,必须将这些操作数转换为彼此兼容。此转换的条件运算符的规则相当复杂;但当操作数具有不同类型且可转换为数字时,将应用二进制数字提升。
在提供一个装箱操作数和一个原始操作数的情况下,二进制数字提升的效果是尝试对装箱操作数进行拆箱,而不是对原始操作数进行装箱。
您可以使用其他多操作数运算符观察二进制数字提升,例如+
:
System.out.println(1 + (Integer) null); // NullPointerException!
使用条件运算符,如果显式对 1 进行装箱,则不会得到 NPE,因为操作数的类型不不同:
Integer n = obj[0] == null ? (Integer)obj[0] : Integer.valueOf(1);
添加回答
举报
0/150
提交
取消