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

use*_*ful 18 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
    }
}
Run Code Online (Sandbox Code Playgroud)

输出:

3
?
Run Code Online (Sandbox Code Playgroud)

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

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

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

关于这个概念在java/general中的任何好的参考将非常感激.

Rem*_*eau 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编码的字节(或依赖于endian)?存储在String内存存储中,但是使用使用任何操作系统编码的三个字节存储在字节数组中默认字符集是.0x6E 0xFF0xFF 0x6EgetBytes()

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