1. 程式人生 > 實用技巧 >java 三目運算子

java 三目運算子

三目運算以及自動拆箱導致的NPE

System.out.println(false ? 1 : (Long)null); // NPE
System.out.println(false ? Long.valueOf(1L) : (Long)null);
System.out.println(false ? 1 : (String) null);

  使用 javap -v 檢視位元組碼可以看到

     9: invokevirtual #35                 // Method java/lang/Long.longValue:()J
        12: invokevirtual #39                 // Method java/io/PrintStream.println:(J)V
        15: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
        18: aconst_null
        19: checkcast     #33                 // class java/lang/Long
        22: invokevirtual #27                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V
        25: getstatic     #21                 // Field java/lang/System.out:Ljava/io/PrintStream;
        28: aconst_null
        29: checkcast     #42                 // class java/lang/String
        32: invokevirtual #27                 // Method java/io/PrintStream.println:(Ljava/lang/Object;)V

  可以看到 " false ? 1 : (Long)null" 中對應的關鍵的程式碼 Long.longValue(); 正式由於自動拆箱的操作導致了NPE;

當三目運算條件為false時,當":"左側為基本資料型別,而右側為基本型別的包裝型別時,則會引發包裝型別的自動拆箱操作;(這句話更完整的解釋為,當根據條件判斷時,如果選擇的表示式為基本型別的包裝型別,而未被選擇的表示式為基本型別,則選擇的結果會自動進行拆箱操作)

以下是官方文件的解釋

https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.25

  • If one of the operands is of typeT, whereTisByte

    ,Short, orCharacter, and the other operand is a constant expression (§15.28) of typeintwhose value is representable in the typeUwhich is the result of applying unboxing conversion toT, then the type of the conditional expression isU.