java utf8编码 - char,字符串类型

时间:2012-08-29 22:59:51

标签: java utf-8

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
    }
}

输出:

3
ヨ

请帮我理解这一点。试图了解utf8编码在java中的工作原理。 按照java doc定义的char char:char数据类型是一个16位Unicode字符。

这是否意味着java中的char类型只能支持那些可以用2个字节表示而不是更多的unicode字符?

在上面的程序中,为该字符串分配的字节数是3但是在第三行中返回第一个字符(java中的2个字节)可以容纳一个3字节长的字符? 真的很困惑吗?

在java / general中对这个概念的任何好的参考都会非常感激。

4 个答案:

答案 0 :(得分:33)

您的代码示例中没有任何内容直接使用UTF-8。 Java字符串使用UTF-16编码在内存中。不适合单个16位字符的Unicode代码点将使用称为代理项对的2字符对进行编码。

如果未将参数值传递给String.getBytes(),它将返回一个字节数组,其中String内容使用底层操作系统的默认字符集进行编码。如果要确保UTF-8编码的阵列,则需要使用getBytes("UTF-8")

调用String.charAt()仅返回String的内存存储中的原始UTF-16编码字符。

因此,在您的示例中,Unicode字符使用UTF-16编码的两个字节(String0x6E 0xFF存储在0xFF 0x6E内存中存储中取决于endian),但是使用三个字节存储在getBytes()的字节数组中,这三个字节使用操作系统默认字符集进行编码。

在UTF-8中,该特定Unicode字符也恰好使用3个字节(0xEF 0xBD 0xAE)。

答案 1 :(得分:4)

String.getBytes()使用平台的默认字符编码返回字节,该编码不一定与内部表示匹配。

在大多数情况下,你最好不要使用这种方法,因为在大多数情况下依赖平台的默认编码是没有意义的。请改用String.getBytes(String charsetName)并明确指定应该用于将String编码为字节的字符集。

答案 2 :(得分:3)

UTF-8是一种可变长度编码,对于ASCII字符(0到127之间的值)只使用一个字节,对其他unicode符号使用两个,三个(甚至更多)字节。

这是因为字节的高位用于表示“这是一个多字节序列”,因此8位上的一位不用于实际表示“实际”数据(字符代码),而是用于标记字节

所以,尽管Java在ram中为每个char使用2个字节,但是当使用UTF-8“序列化”字符时,它们可能在结果字节数组中产生一个,两个或三个字节,这就是UTF-8编码的工作原理

答案 3 :(得分:2)

这就是Java represents characters

的方式