2012-08-29 180 views
13
public class UTF8 { 
    public static void main(String[] args){ 
     String s = "ヨ"; //0xFF6E 
     System.out.println(s.getBytes().length);//length of the string 
     System.out.println(s.charAt(0));//first character in the string 
    } 
} 

輸出:的java utf8編碼 - 字符,字符串類型

3 
ヨ 

請幫助我理解這一點。試圖瞭解utf8編碼如何在java中工作。 根據char char的定義char char:char數據類型是一個單一的16位Unicode字符。

這是否意味着在Java中char類型只能支持,可以用2個字節來表示,並沒有比這更那些Unicode字符?

在上述程序中,無分配給該字符串的字節是3,但在第三行,它返回第一個字符(2個字節在Java)可以容納一個字符是3個字節長? 真的很困惑嗎?

關於Java的這個概念有什麼好的參考/一般將非常感激。

+0

另請參閱[Unicode FAQ](http://www.unicode.org/faq/utf_bom.html#gen0)。 – McDowell

回答

27

你的代碼示例中沒有直接使用UTF-8。 Java字符串使用UTF-16編碼在內存中。不符合單個16位字符的Unicode代碼點將使用稱爲代理對的2個字符對進行編碼。

如果您未將參數值傳遞給String.getBytes(),它將返回一個字節數組,其中String內容使用基礎操作系統的默認字符集進行編碼。如果你想確保一個UTF-8編碼數組,那麼你需要使用getBytes("UTF-8")來代替。

調用String.charAt()返回字符串的唯一的內存中存儲的原始UTF-16編碼炭。

在你的例子

所以,Unicode字符使用是UTF-16編碼(取決於端0x6E 0xFF0xFF 0x6E)兩個字節被存儲在String內存存儲,但使用被存儲在字節數組中從getBytes()三個字節使用任何OS默認字符集進行編碼。

在UTF-8中,該特定的Unicode字符恰好也使用3個字節(0xEF 0xBD 0xAE)。

+0

我想他的系統默認編碼是UTF-8 –

3

UTF-8是一個可變長度編碼,使用(0和127之間的值),用於ASCII字符只有一個字節,和兩個,三個(或甚至更多)對其他的Unicode符號字節。

這是因爲字節的高位用於告訴「這是一個多字節序列」,所以8中的一位不用於實際表示「真實」數據(char代碼),而是用於標記字節。因此,儘管Java在每個字符的ram中使用2個字節,但當字符使用UTF-8「串行化」時,它們可能會在生成的字節數組中產生一個,兩個或三個字節,這就是UTF-8編碼作品。

+0

UTF-8最多使用2個字節 – adosaiguas

+3

UTF-8最多使用4個字節,而不是2個字節(如果在UTF-8修改爲不超過UTF-16的代碼點之前考慮舊的UTF-8規格,則爲6個字節支持)。 –

+0

@adosaiguas「UTF-8使用一到四個8位字節對Unicode字符集中的1,112,064 [7]個代碼點進行編碼」(維基百科) –

4

String.getBytes()返回使用平臺的默認字符編碼這並不一定匹配內部表示的字節數。

你最好永遠不會使用在大多數情況下,這種方法的,因爲在大多數情況下,它沒有意義依賴於平臺的默認編碼。改爲使用String.getBytes(String charsetName),並明確指定應將字符串編碼爲字節的字符集。