Java 长度为null的三元表达式中的NullPointerException

Java 长度为null的三元表达式中的NullPointerException,java,nullpointerexception,Java,Nullpointerexception,为什么下面的代码行会产生NullPointerException Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null; 我知道正在对null执行取消装箱,但为什么 注意 Long v = (Long) null; 不会产生异常。来自 如果第二个和第三个操作数具有相同的类型(可能是null类型),则这就是条件表达式的类型 如果第二个和第三个操作数中的一个为布尔型,另一个为布尔型,则 条件表达式是布尔的 在下面的语句中,第二个操作数的类型是long,第三

为什么下面的代码行会产生
NullPointerException

Long v = 1 == 2 ? Long.MAX_VALUE : (Long) null;
我知道正在对
null
执行取消装箱,但为什么

注意

Long v = (Long) null;
不会产生异常。

来自

  • 如果第二个和第三个操作数具有相同的类型(可能是null类型),则这就是条件表达式的类型
  • 如果第二个和第三个操作数中的一个为
    布尔型
    ,另一个为
    布尔型
    ,则 条件表达式是
    布尔的
  • 在下面的语句中,第二个操作数的类型是
    long
    ,第三个操作数的类型是
    long

    Long v = 1 == 2 ? Long.MAX_VALUE :  (Long) null;
    
    如果表达式为true,则此操作有效

    Long v= 1 == 1 ?  Long.MAX_VALUE : (Long) null;
    
    或者你可以投

    Long v= 1 == 2 ?  Long.valueOf(Long.MAX_VALUE) : (Long) null;
    

    因此,很明显,如果条件为真,则只需装箱,如果条件为假,则不应装箱。但是,三元运算符表达式必须具有特定的静态类型。所以我们有
    Long
    Long
    。JLS声明结果将是原语(如果操作符是,比如说,
    +
    或者甚至是
    =
    ),也可以想象一下)。因此,三元运算符将强制取消装箱,只有这样赋值才会导致装箱

    如果要用等价的
    If else
    替换代码,则只需将
    long
    赋值为
    long
    ,并将
    long
    赋值为
    long
    ,这样就不会进行任何拆箱,因此运行良好


    IIRC,这是Bloch&Gafter的Java拼图。

    你做一个v=((1==2)?Long.MAX_值:(Long)null);这总是错误的,所以您总是尝试将null强制转换为Long。这似乎是不允许的,并引发您的异常。为什么会有这样一行代码?智力好奇还是实际生产代码中的一个片段?@Paul and evildead看起来像是演示取消装箱顺序的示例代码。它与相关的所有内容都有关:解决方案是在返回
    Long
    时将该强制转换移动到
    Long.MAX_值
    。是的,我知道它正在进行取消装箱,而且你不能取消对null的装箱。我在问为什么在这种情况下它会尝试执行拆箱。这并不完全正确。他正试图解装箱一个空
    对象;演员阵容不是问题。您可以对任何类型的对象强制转换
    null
    ,请参阅Java语言规范中的“如果对引用类型的强制转换不是编译时错误,则有几种情况:”