Java 当编写if-else编译器抱怨时,但对于速记来说,它不会抱怨,为什么?
在Java中,当我这样写的时候Java 当编写if-else编译器抱怨时,但对于速记来说,它不会抱怨,为什么?,java,if-statement,nullpointerexception,return,Java,If Statement,Nullpointerexception,Return,在Java中,当我这样写的时候 public int method(boolean b) { if (b) return null; else return 0; } 编译器抱怨不兼容的类型,但如果用速记代替它 public int method(boolean b) { return (b ? null : 0); } 编译器不会抱怨,而且会出现NPE。 所以我的问题是 为什么编译器不抱怨 为什么NPE 这是由自动取消装箱和类型推断的
public int method(boolean b) {
if (b)
return null;
else
return 0;
}
编译器抱怨不兼容的类型
,但如果用速记代替它
public int method(boolean b) {
return (b ? null : 0);
}
编译器不会抱怨,而且会出现NPE
。
所以我的问题是
NPE
这是由自动取消装箱和类型推断的组合造成的 在这两种情况下,从类型签名可以清楚地看出,该方法必须返回
int
在第一种情况下,显式返回null
,这是不可分配给int
,因此编译器正确地抱怨这是一个错误
在第二种情况下,您正在创建一个匿名值(括号中的位),因此编译器必须推断它的类型。它计算出0
和null
最具体的常见超类型是Integer
——这是正确的。因此,您的return语句返回的是Integer
-类型的内容,这与int
兼容,它只是在运行时自动解除绑定。当虚拟机试图将空引用转换为int
时,正是这种自动取消绑定抛出了NPE
如果它能帮助您更好地将其可视化,那么您的第二个示例基本上与以下示例相同:
public int method(boolean b) {
Integer tmp = (b ? null : 0);
return tmp;
}
因此编译器没有什么可抱怨的(两行代码本身都很好)
这里的错误(如果有的话)是自动取消装箱,并且默默地假装
Integer
与int
的类型相同。正是由于这个原因,它不是。问题在于您要返回的类型。
不能将null赋值给基元类型。
这是一个半答案,我不知道为什么它在速记版中没有抱怨。2。NPE,因为在null上调用Integer.intValue()。原语类型int不能为null,啊,这解释了为什么
return(Integer)null第一个示例中的code>使编译错误消失,但在运行时保留NPE
工作正常,您不需要显式的intValue()
调用,因为Java会毫无怨言地自动取消装箱。@azurefrog-正确-但它更清楚地说明了NPE的来源。第二种情况与“匿名值”无关。所使用的是:“第二个/第三个操作数中的一个是原语类型T,另一个是对T应用装箱转换的结果,然后类型…是T”:因此,它将三元数的结果计算为int
,可以返回(§14.17),因为它可分配给int
。这就是该方法编译的原因。然后字节码被编译为Integer.intValue()null
(然后是box,然后是unbox 0),这将在运行时抛出NPE。字符串不是基元类型。True!我有点精神失常,因为工作太多了。我会更正答案的。