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

Ani*_*mj' 4 java if-statement return nullpointerexception

在Java中我这样写的时候

public int method(boolean b) {
    if (b)
        return null;
    else
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译器抱怨incompatible types,但如果用速记替换它

public int method(boolean b) {
    return (b ? null : 0);
}
Run Code Online (Sandbox Code Playgroud)

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

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

And*_*yle 7

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

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

在第一种情况下,您显式返回null,这是不可分配的int,因此编译器正确地抱怨这是一个错误.

在第二种情况下,您将创建一个匿名值(括号中的位),因此编译器必须推断它的类型.它的工作原理指出,最具体的共同超0nullInteger-这是正确的.因此,你的return语句返回类型的东西Integer- 这兼容的int,它只是在运行时自动取消装箱.当VM尝试将空引用转换为时,正是这种自动拆箱会抛出NPE int.

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

public int method(boolean b) {
    Integer tmp = (b ? null : 0);
    return tmp;
}
Run Code Online (Sandbox Code Playgroud)

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

这里的错误(如果有的话)是自动拆箱,并且默默地假装Integer与此类型相同int.事实并非如此.