3項if-elseの自動開梱の必要性


23

このコードは正常に動作します:-

    Integer nullInt = null;
    if (1 <= 3) {
        Integer secondNull = nullInt;
    } else {
        Integer secondNull = -1;
    }
    System.out.println("done");

しかし、これはnullポインター例外をスローしますが、Eclipseは自動アンボックス化の必要があることを警告します:-

    Integer nullInt = null;
    Integer secondNull = 1 <= 3 ? nullInt : -1;
    System.out.println("done");

なぜそうなのですか、誰かが案内してくれますか?

回答:


22

三項条件式のタイプ

1 <= 3 ? nullInt : -1

is int(JLSには、2番目と3番目のオペランドのタイプに応じて、3項条件演算子のタイプを説明するいくつかのテーブルが含まれています)。

したがって、にボックス化解除しようとnullIntするintと、NullPointerExceptionがスローされます。

if-elseスニペットの動作を取得するには、次のように記述する必要があります。

1 <= 3 ? nullInt : Integer.valueOf(-1)

これで式のタイプはになるIntegerため、ボックス化解除は行われません。


4
ただ、あなたの答えに追加するには、ここで言及したテーブルは以下のとおりです。docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.25
Amongalen

3

三項演算子の引数はこれと同じ型である必要があると確信しています。-1と一部の定数nullintコンパイラを使用nullintしているため、値を取得するためにボックス化解除を試みます。そして、それをオートボックスしてsecondNull変数に格納します。


3

これは、条件演算子の2つのオペランド? :がプリミティブ型とそのボックス化参照型の場合、ボックス化解除変換が行われるためです(JLS§15.25.2)。

数値条件式のタイプは、次のように決定されます。

  • ...
  • 2番目と3番目のオペランドの一方がプリミティブ型Tであり、もう一方の型がTにボクシング変換(§5.1.7)を適用した結果である場合、条件式の型はTです。

一般的に、式自体をコンパイル時の型にする必要があるため、ifステートメントを? :式で置き換えても、コードの意味が常に保持されるわけではありません? :。つまり、2つのオペランドのタイプが異なる場合、結果が一貫したコンパイル時のタイプになるように、一方または両方に変換を行う必要があります。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.