2012-08-29 122 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),并明确指定应将字符串编码为字节的字符集。