Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/359.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 当编写if-else编译器抱怨时,但对于速记来说,它不会抱怨,为什么?_Java_If Statement_Nullpointerexception_Return - Fatal编程技术网

Java 当编写if-else编译器抱怨时,但对于速记来说,它不会抱怨,为什么?

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 这是由自动取消装箱和类型推断的

在Java中,当我这样写的时候

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使编译错误消失,但在运行时保留NPE
    工作正常,您不需要显式的
    intValue()
    调用,因为Java会毫无怨言地自动取消装箱。@azurefrog-正确-但它更清楚地说明了NPE的来源。第二种情况与“匿名值”无关。所使用的是:“第二个/第三个操作数中的一个是原语类型T,另一个是对T应用装箱转换的结果,然后类型…是T”:因此,它将三元数的结果计算为
    int
    ,可以返回(§14.17),因为它可分配给
    int
    。这就是该方法编译的原因。然后字节码被编译为
    Integer.intValue()null
    (然后是box,然后是unbox 0),这将在运行时抛出NPE。字符串不是基元类型。True!我有点精神失常,因为工作太多了。我会更正答案的。