编写 if-else 编译器时会报错,但 shorthand 却不会报错,为什么?
When writing if-else compiler complains but for shorthand it does not, why?
在Java的时候我是这样写的
public int method(boolean b) {
if (b)
return null;
else
return 0;
}
编译器抱怨 incompatible types
,但如果将其替换为 shorthand
public int method(boolean b) {
return (b ? null : 0);
}
编译器不会报错,而且会有一个NPE
。
所以我的问题是
- 为什么编译器不报错
- 为什么
NPE
?
这是由自动拆箱和类型推断共同造成的。
在这两种情况下,从类型签名可以清楚地看出该方法必须 return 一个 int
.
在你的第一种情况下,你显式 returning null
,它不能分配给 int
,所以编译器正确地抱怨这是一个错误。
在第二种情况下,您正在创建一个匿名值(括号中的位),因此编译器必须推断它的类型。结果表明 0
和 null
最具体的常见超类型是 Integer
- 这是正确的。因此,您的 return 语句是 returning 类型 Integer
的东西 - 而这个 是 与 int
兼容,它只是自动- 在运行时拆箱。当 VM 尝试将空引用转换为 int
.
时,正是这种自动拆箱引发了 NPE
如果它能帮助你更好地形象化,你的第二个例子本质上是一样的:
public int method(boolean b) {
Integer tmp = (b ? null : 0);
return tmp;
}
因此编译器没有什么可抱怨的(这两行本身都很好)。
这里的错误,如果有的话,是自动拆箱,并默默地假装 Integer
与 int
是同一类型。事实并非如此。
问题是您想要 return 的类型。
您不能将 null 分配给原始类型。
这是一个一半的答案我不知道为什么它在shorthand版本中没有抱怨。
在Java的时候我是这样写的
public int method(boolean b) {
if (b)
return null;
else
return 0;
}
编译器抱怨 incompatible types
,但如果将其替换为 shorthand
public int method(boolean b) {
return (b ? null : 0);
}
编译器不会报错,而且会有一个NPE
。
所以我的问题是
- 为什么编译器不报错
- 为什么
NPE
?
这是由自动拆箱和类型推断共同造成的。
在这两种情况下,从类型签名可以清楚地看出该方法必须 return 一个 int
.
在你的第一种情况下,你显式 returning null
,它不能分配给 int
,所以编译器正确地抱怨这是一个错误。
在第二种情况下,您正在创建一个匿名值(括号中的位),因此编译器必须推断它的类型。结果表明 0
和 null
最具体的常见超类型是 Integer
- 这是正确的。因此,您的 return 语句是 returning 类型 Integer
的东西 - 而这个 是 与 int
兼容,它只是自动- 在运行时拆箱。当 VM 尝试将空引用转换为 int
.
如果它能帮助你更好地形象化,你的第二个例子本质上是一样的:
public int method(boolean b) {
Integer tmp = (b ? null : 0);
return tmp;
}
因此编译器没有什么可抱怨的(这两行本身都很好)。
这里的错误,如果有的话,是自动拆箱,并默默地假装 Integer
与 int
是同一类型。事实并非如此。
问题是您想要 return 的类型。 您不能将 null 分配给原始类型。 这是一个一半的答案我不知道为什么它在shorthand版本中没有抱怨。