编写 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。 所以我的问题是

  1. 为什么编译器不报错
  2. 为什么 NPE

这是由自动拆箱和类型推断共同造成的。

在这两种情况下,从类型签名可以清楚地看出该方法必须 return 一个 int.

在你的第一种情况下,你显式 returning null,它不能分配给 int,所以编译器正确地抱怨这是一个错误。

在第二种情况下,您正在创建一个匿名值(括号中的位),因此编译器必须推断它的类型。结果表明 0null 最具体的常见超类型是 Integer - 这是正确的。因此,您的 return 语句是 returning 类型 Integer 的东西 - 而这个 int 兼容,它只是自动- 在运行时拆箱。当 VM 尝试将空引用转换为 int.

时,正是这种自动拆箱引发了 NPE

如果它能帮助你更好地形象化,你的第二个例子本质上是一样的:

public int method(boolean b) {
    Integer tmp = (b ? null : 0);
    return tmp;
}

因此编译器没有什么可抱怨的(这两行本身都很好)。

这里的错误,如果有的话,是自动拆箱,并默默地假装 Integerint 是同一类型。事实并非如此。

问题是您想要 return 的类型。 您不能将 null 分配给原始类型。 这是一个一半的答案我不知道为什么它在shorthand版本中没有抱怨。