2010-10-25 102 views
9

爲什麼這個編譯Java 6中(孫1.6.0_16):解析Java 6字符串文字中的unicode轉義問題...?

System.out.println("\u000B"); 

...但不是這樣的:

System.out.println("\u000A"); 

在此程序:

public class Test { 
    public static void main(String argv[]) { 
    System.out.println("\u000A"); 
    } 
} 

我得到a

Test.java:3: unclosed string literal 
System.out.println("\u000A"); 

這裏發生了什麼?

回答

17

問題在於編譯時很早就完成了Unicode替換。 Unicode轉義不僅在字符串和字符文字中有效(如其他轉義序列,例如\t) - 它們在代碼中的任何地方都是有效的。他們被描述在規範的不同區域 - section 3.3而不是section 3.10.6;只有後者是大約字符和字符串文字轉義序列。

基本上,讀取該規範第3條對詞法結構:)更多細節

所以,你的代碼是實際上等同於:

public class Test { 
    public static void main(String argv[]) { 
    System.out.println(" 
"); 
    } 
} 

...這顯然是無效的碼。對於回車和換行,基本上最好使用「\ r」和「\ n」轉義序列。

我個人認爲這處理的Unicode轉義爲Java中的漏洞,但不是很多,我們可以做些什麼,現在:(

+1

有人可以根據Jon Skeet的回答提出像可汗學院一樣的視頻教程。尊重。 – 2010-10-25 08:38:21

+0

非常感謝! – daf 2010-10-25 18:40:44

3

的Unicode轉義之前詞法分析擴大。 事實上,出現的Unicode轉義內文字串是無關緊要的。 參見JLS 3.2。

1

這是因爲\ u000a = \ n並且編譯器會處理java源代碼以將其轉換爲令牌,因此您不能在代碼中使用該Unicode字符。同爲\ u000d = \ r

1

如果我沒有記錯的話,避免prepocessing我們可以通過改變線路中解決它:

System.out.println((char)10); 

的限制是通過作爲一個CHAR,它的擴展將從0到255.