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);
    }
}

このコードは正常にコンパイルされます。すべての式は、最終的に型変数に割り当てようnullとします。Integerexp1exp2exp3

最初の2つのケースでは、例外をスローせずexp1 = null exp2 = null、明らかな結果を生成します。

ただし、最後のケースを注意深く調べると、型変数nullへの割り当ても試行され、前の2つのケースと似ていますが、がスローされることがわかります。なぜそれが起こるのですか?Integerexp3NulllPointerException

質問を投稿する前に、この素​​敵な質問を参照しましが、この場合、JLSで指定されているルールがここで適用されていることがわかりませんでした。

4

2 に答える 2

13

割り当ては、ではなく、によるものであるため、nullはボックスから解放されています。ただし、aは、として表すことはできません。したがって、。int5intIntegernullintNullPointerException

に置き換える5new Integer(5)、機能します。

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

参照:

于 2012-10-17T15:10:59.013 に答える
2

箱から出さnullれているので、式の他の2つの値と同じタイプ?:です。これをトリガーしないexp1でください。exp2

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 に答える