次のコードの実行中に、行でNullPointerException
を取得しています:
_value = condition ? getDouble() : 1.0;
_
以前の行でgetDouble()
の代わりにnull
を使用すると、すべてが機能し、これは奇妙です。
_public class Test {
static Double getDouble() {
return null;
}
public static void main(String[] args) {
boolean condition = true;
Double value;
value = condition ? null : 1.0; //works fine
System.out.println(value); //prints null
value = condition ? getDouble() : 1.0; //throws NPE
System.out.println(value);
}
}
_
誰かがこの行動を理解するのを助けることができますか?
書くとき
_value = condition ? null : 1.0;
_
_condition ? null : 1.0
_の型は参照型である必要があるため、型はDouble
であり、値null
を保持できます。
書くとき
_value = condition ? getDouble() : 1.0;
_
getDouble()
はnull
を返します。これは次の記述と同等です。
_value = condition ? ((Double) null) : 1.0;
_
この場合、コンパイラはDouble
とdouble
を三項条件演算子の2番目と3番目の引数として認識し、式のタイプがdouble
であると決定します。したがって、null
をdouble
に展開し、NullPointerException
を取得します。
条件付き三項演算子のタイプは、 JLS 15.25 のいくつかのテーブルによって決定されます。
第2および第3オペランドがnull
およびdouble
である場合、条件式のタイプはDouble
およびnull
の最小上限、つまりDouble
。
第2および第3オペランドがDouble
およびdouble
の場合、条件式のタイプはdouble
です。
#jls-15.25 を参照してください:
第2オペランドがDouble
であり、第3オペランドがdouble
である場合、結果は次のようになります。
getCount() == 1 ? getDouble() : 1.0
double
になります。
そして、_Double null
_(getDouble()
によって返される)をdouble
に変換しようとすると、NPE
がスローされます。