在编写if-else编译器时会抱怨,但为了速记,它不会,为什么?

时间:2015-01-19 15:58:04

标签: java if-statement nullpointerexception return

在Java中我这样写的

public int method(boolean b) {
    if (b)
        return null;
    else
        return 0;
}

编译器抱怨incompatible types,但是如果用简写替换

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

编译器不会抱怨,而且会有NPE。 所以我的问题是

  1. 为什么编译器没有抱怨
  2. 为什么NPE

2 个答案:

答案 0 :(得分:7)

这是由自动拆箱和类型推断的组合引起的。

在这两种情况下,类型签名都清楚该方法必须返回int

在第一种情况下,您明确返回null,这不能分配给int,因此编译器正确地抱怨这是一个错误。

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

如果它可以帮助您更好地将其可视化,那么您的第二个示例基本上与:

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

所以编译器没有什么可抱怨的(这两行都是好的)。

此处的错误(如果有的话)是自动取消装箱,并默默假装Integerint的类型相同。不正是出于这个原因。

答案 1 :(得分:-1)

问题是您要返回的类型。 您不能将null分配给基本类型。 这是一个半答案,我不知道为什么它不会在速记版本中抱怨。