Java字符数组是否始终是有效的UTF-16(大端)编码?

Java字符数组是否始终是有效的UTF-16(大端)编码?,java,arrays,unicode,character-encoding,char,Java,Arrays,Unicode,Character Encoding,Char,假设我将Java字符数组(char[])实例编码为字节: 每个字符使用两个字节 使用big-endian编码(最左边存储最高有效8位,最右边存储最低有效8位) 这是否总是创建有效的UTF-16BE编码?如果不是,哪些代码点将导致无效编码 这个问题与and非常相关。否。您可以创建包含您想要的任何16位值的char实例——没有任何东西可以将它们约束为有效的UTF-16代码单元,也没有任何东西可以将它们的数组约束为有效的UTF-16序列。即使是字符串也不要求其数据为有效的UTF-16: char

假设我将Java字符数组(
char[]
)实例编码为字节:

  • 每个字符使用两个字节
  • 使用big-endian编码(最左边存储最高有效8位,最右边存储最低有效8位)
这是否总是创建有效的UTF-16BE编码?如果不是,哪些代码点将导致无效编码



这个问题与and非常相关。

否。您可以创建包含您想要的任何16位值的
char
实例——没有任何东西可以将它们约束为有效的UTF-16代码单元,也没有任何东西可以将它们的数组约束为有效的UTF-16序列。即使是
字符串
也不要求其数据为有效的UTF-16:

char data[] = {'\uD800', 'b', 'c'};  // Unpaired lead surrogate
String str = new String(data);
对有效UTF-16数据的要求在Unicode标准的定义中有规定(基本上,所有数据都必须是Unicode标量值,并且所有代理必须正确配对)。您可以使用
CharsetEncoder
测试字符数组是否为有效的UTF-16序列,并将其转换为UTF-16BE(或LE)字节序列:

CharsetEncoder encoder = Charset.forName("UTF-16BE").newEncoder();
ByteBuffer bytes = encoder.encode(CharBuffer.wrap(data)); // throws MalformedInputException
(同样,如果您有字节,则使用
CharsetDecoder

如果
String
仅包含有效的Unicode,则
tocharray()
必然是有效的UTF-16BE--但是,正如我所提到的,
String
不会验证其内容,因此由您检查这一点。