2017-12-01 1 views
3

このコードはどのようにコンパイルされますか?コンパイラが「型の不一致:nullからbooleanに変換できません」と不平を言うことを期待していましたが、そうではありません。実行時にNullPointerExceptionで失敗します。返り値が3値演算子を使用するとき、どのようにしてブール値を返すメソッドがコンパイルされるのでしょうか?

public static void main(String[] args) throws Exception { 
    System.out.println("this throws a NPE: " + whyIsThisPossible(1, 2)); 
} 

private static boolean whyIsThisPossible(int a, int b) { 
    return a + b == 2 ? true : null; 
} 

Exception in thread "main" java.lang.NullPointerException 
at FunkyMethodTest.whyIsThisPossible(FunkyMethodTest.java:10) 
at FunkyMethodTest.main(FunkyMethodTest.java:5)* 

答えて

0

3進数の最初の部分は、オペランドの種類を決定します。この場合、プリミティブbooleanです。あなたは(構文的に)booleanに(技術的にNullTypeのある)nullをキャストすることができ

return a + b == 2 ? true : null; 

注意、しかし、それはNullPointerExceptionになります。したがって、コードがコンパイルされている間に、a + b2と等しくない場合、NullPointerExceptionが得られます。それは構文的に法的である理由については、Boolean.FALSEBooleanで、autounboxingはこのコードが正常に動作することを意味し

return a + b == 2 ? true : Boolean.FALSE; 

注意を検討してください。

3

Javaは、3進表現のタイプをbooleanとみなします。コンパイラはnullBooleanと扱います。すなわち、ボクシング変換をプリミティブ型booleanに適用した結果です。次のように

15.25条件式の種類が決定される:ここ

は言語仕様の関連部分は...

  • の1つが第2オペランドおよび第3オペランドはプリミティブタイプTであり、他方はにボクシング変換(5.1.7)を適用した結果であるの場合、条件式のタイプはTです。

言語仕様とき式の条件によって選択されたオペランドに必要ボクシング/アンボクシング変換が適用されると述べています。これは、コードがbooleannullからunboxするときに例外をトリガーするものです。

0

このreturn a + b == 2 ? true : (Boolean) x;は実際には起こりますが、実際には書くことはできませんが、コンパイラは不平を言うでしょう。しかし、あなたは書くことができます:

private static boolean whyIsThisPossible(int a, int b) { 
    Boolean x = null; 
    if (a == b) { 
     x = false; 
    } 
    return a + b == 2 ? true : (Boolean) x; 
} 
関連する問題