2016-09-08 35 views
0

在Java中,如果我寫:
System.out.println((String) null);,我得到"null"爲什麼Java將空引用轉換爲String「null」?

這似乎很奇怪。有誰知道爲什麼設計師選擇這種方法?在我看來,這是一個「無中生有」的案例。我讀過JLS entry on cast operators,和它說:

類型強制轉換表達式的是將捕獲轉換(§5.1.10),以他的名字在括號中出現的類型的結果。
即使操作數表達式的結果是一個變量,轉換表達式的結果也不是一個變量,而是一個值。

跳到entry on capture conversion,我看到一般類型定義捕獲轉化率,但是該條目添加:

捕獲轉換比上一個參數化類型之外的任何類型(§4.5)充當標識轉換(§5.1.1)。

好吧!關於entry on identity conversion,這裏有:

對於任何類型都允許從類型到同一類型的轉換。

在這種情況下,該類型是String,但要轉換的事情是null並給我留下困惑。但事實證明,Java實際上是使用字符串轉換爲(String) null。該JLS entry on String conversion說:

任何類型都可以轉換由字符串轉換String類型...
如果引用爲null,它被轉換爲字符串「NULL」(1-4個ASII碼N,U,二)。

,這引起了

的一個問題是這樣的:

HashMap map = new HashMap(); 
System.out.println((String)map.get("something")); 

該程序打印"null"。我如何知道是否因爲入口是null而HashMap中的String值爲「null」(四個ASCII字符'n','u','l','l')?現在我知道有人會說Java不鼓勵使用raw types,並且類型HashMap應該參數化,但解決方案是什麼?

+0

你期望它做什麼? –

+0

可能拋出'NullPointerException' – Nayuki

+0

每個人都使用'System.out.println'來嘗試調試;如果用於調試的主要工具本身會引發異常,它將不會很好地運行。這是一個務實的選擇,使實際的事情不那麼令人驚訝,而不是完全合乎邏輯的事情。 –

回答

-1

你正在推翻這一點。 Java不會將(值)null轉換爲(字符串)"null"。正確的答案是,這只是PrintStream.println(String)方法的明確行爲:

打印一個字符串,然後終止該行。該方法的行爲如同調用print(String),然後調用println()

接下來我們請教什麼PrintStream.print(String)不得不說:

打印的字符串。如果參數是null,則打印字符串"null"。否則,根據平臺的默認字符編碼將字符串的字符轉換爲字節,並且這些字節的寫入方式與write(int)方法完全相同。

(記住,的System.out類型是PrintStream。)

-1
HashMap map = new HashMap(); 
System.out.println((String)map.get("something")); 

該程序打印"null"。我怎麼知道它是否是因爲 條目是null而HashMap中的字符串的值是「null」 (四個ASCII字符'n','u','l','l')?

目前仍然null"null"之間的差別,你就不能看,當你打印出來與System.out.println。他們是不同的價值觀,和他們做比較是不同的:

HashMap map = new HashMap(); 
map.put("foo", "null"); 
String something = (String) map.get("something"); 
String foo = (String) map.get("foo"); 
System.out.println(something == null); // true 
System.out.println(foo == null); // false 
System.out.println("null".equals(something)); // false 
System.out.println("null".equals(foo)); // true 
-1

它確實無關,與鑄造,但打印:如果你施放null到字符串,它仍然是一個null

String s=(String)null; 
if (s==null) 
{ 
    System.out.println("It is still a null"); 
} 
else 
{ 
    throw new RuntimeException("This won't happen"); 
} 

因此,您應該沒有任何困難來檢查Map,Collection或任何API返回的值是否爲空,只需通過程序執行直接比較。

另一方面,絕對不要相信PrintStream(如System.out)直接打印到標準輸出的結果。請參閱PrintStream.print(String)的文檔。

此外:打印數字或布爾值時會出現相同的歧義:如果您在標準輸出「123」中看到,是數字值還是字符串值?我堅持:要檢查值,不要相信打印到PrintStream的字符串的外觀。