7

可能的重复:
NullPointerException 通过 Java 三元运算符的自动装箱行为

以下代码使用简单的条件运算符。

public class Main
{
    public static void main(String[] args)
    {
        Integer exp1 = true ? null : 5;
        Integer exp2 = true ? null : true ? null : 50;

        System.out.println("exp1 = " +exp1+" exp2 = "+exp2);

        Integer exp3 = false ?  5 : true ? null: 50; //Causes the NullPointerException to be thrown.

        System.out.println("exp3 = "+exp3);
    }
}

这段代码编译得很好。所有的表达式最终都试图分别分配nullInteger类型变量exp1,exp2exp3

前两种情况不会引发任何异常并产生exp1 = null exp2 = null显而易见的结果。

然而,最后一种情况,如果你仔细看,你会看到它也尝试分配null类型Integer变量exp3,看起来与前两种情况类似,但它会导致NulllPointerException抛出。为什么会这样?

在我发布我的问题之前,我已经提到了这个很好的问题,但在这种情况下,我找不到 JLS 指定的规则适用于此处。

4

2 回答 2

13

null正在拆箱到 an int,因为分配是由于5an ,而int不是 an Integer。但是,anull不能表示为int,因此NullPointerException.

如果您替换5new Integer(5),那么它将起作用。

Integer exp3 = false ? new Integer(5) : true ? null : 50;

也可以看看:

于 2012-10-17T15:10:59.013 回答
2

它正在拆箱,因此它与表达式null中的其他两个值的类型相同。不要触发这个。?:exp1exp2

public class Foo {
    public static void main(String...args) {
        Integer exp3 = false ?  5 : true ? null: 50; //Causes the NullPointerException to be thrown.
        System.out.println("exp3 = "+exp3);
    }  
}

运行后javap -c Foo我们得到这个反汇编:

public static void main(java.lang.String[]);
  Code:
   0:   aconst_null
   1:   checkcast   #2; //class java/lang/Integer
   4:   invokevirtual   #3; //Method java/lang/Integer.intValue:()I
   7:   invokestatic    #4; //Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
   10:  astore_1
   11:  getstatic   #5; //Field java/lang/System.out:Ljava/io/PrintStream;
   14:  new #6; //class java/lang/StringBuilder
   17:  dup
   ....

注 4:invokevirtual #3——它正试图在此处拆箱null

于 2012-10-17T15:11:39.013 回答