2011-09-19 74 views
2

有問題的線路是return pFile.exists() ? true : null;。由於它不會引發任何編譯錯誤,因此解釋是什麼。它最終提高了NPE需要說明:java中的三元運算符

import java.io.File; 
public class Main { 
    public static void main(String... args) { 
    boolean accept = accept(new File("")); 
    System.out.println("accept = " + accept); 
    } 
    public static boolean accept(File pFile) { 
    System.out.println(pFile.exists()); // prints: false, so pFile is not null 
    return pFile.exists() ? true : null; //this line should throw compilation error 
    } 
} 

pFilenull;你可以看到一個File被實例化。但顯然該文件不存在。這個問題不是關於pFile。我對運營商如何處理null感興趣。

+0

爲什麼不直接返回'pFile.exists()'? –

+0

用以下代碼替換accept(File pFile)方法的主體:'return(pFile == null)? false:pFile.exists();'或者不使用三元運算符,你可以說'return(pFile!= null)&& pFile.exists();'。 – styfle

+0

請參閱我的編輯。是的,我可以寫'return pFile.exists();' – Kowser

回答

7

你的代碼就相當於:

public static boolean accept(File pFile) { 
    System.out.println(pFile.exists()); // prints: false, so pFile is not null 
    Boolean tmp = pFile.exists() ? true : null; 
    return (boolean) tmp; 
} 

在換句話說,條件運算符的類型是在這種情況下Boolean,然後該值被拆箱到返回boolean。當null被拆箱時,您會收到一個異常。

從Java語言規範的section 15.25

否則,第二和第三操作數分別爲類型S1和S2的。假設T1是將裝箱轉換應用於S1所產生的類型,並讓T2爲將裝箱轉換應用於S2所得到的類型。條件表達式的類型是將捕獲轉換(第5.1.10節)應用於lub(T1,T2)(第15.12.2.7節)的結果。

我認爲這是適用的情況,儘管我會給予它不盡如人意的地方。

+0

很好的答案,這就是我一直在尋找的。 – Kowser

+0

@Jon,說實話,我發現你的答案是正確的,但過度偏激,並不完全符合要求。你引用了三元運算符規範,事實上,這個問題沒有任何可解決的問題 - 這是對某個表達式pFile.exists()的自動拆箱? true:null'。 –

+0

@Piotr:但它依賴於該表達式的類型是布爾型,然後將其拆箱。所以這不是執行失敗的條件運算符 - 它是執行後的轉換步驟。我認爲這是一個重要的方面。 –

-1

實際上,空字符串正用於創建file。這導致一個空的abstract pathname沒有前綴(或目錄)和空名稱序列。所以Windows無法創建一個file。這又是扔NPE

+0

請看,我的編輯 – Kowser

2

將返回從功能Boolean null定義爲返回boolean(基本類型;注意小b)。 null值自動取消裝箱,並支付NPE。

+0

我也嘗試過你的方式......同樣的事情。 – Kowser

+0

因此,它促進了表達式鍵入'布爾'和盒子和解開'null' ...?只是... y y。 –

+0

它轉換'pFile.exists()的結果? true:null'(是'null')使用auto-unboxing來''boolean'。 'null'自動拆箱會得到NPE –