Java char数组是否始终是有效的UTF-16(Big Endian)编码?
假设我将Java字符数组( char[]
)实例编码为字节:
- 为每个字符使用两个字节
- 使用大端编码(在最左边的最左边存储最高8位,在最右边的字节存储最不重要的8位)
这总是会创建一个有效的UTF-16BE编码吗? 如果不是,哪些代码点将导致无效编码?
这个问题与关于Java char类型的 这个问题以及关于Java字符串的内部表示的这个问题非常相关。
不可以。您可以创建包含任何16位值的char
实例 – 没有任何东西可以将它们限制为有效的UTF-16代码单元,也不会将它们的数组限制为有效的UTF-16序列。 Even String
不要求其数据是有效的UTF-16:
char data[] = {'\uD800', 'b', 'c'}; // Unpaired lead surrogate String str = new String(data);
有效的UTF-16数据的要求在Unicode标准的第3章中列出(基本上,所有内容都必须是Unicode标量值,并且所有代理必须正确配对)。 您可以测试char
数组是否是有效的UTF-16序列,并使用CharsetEncoder
将其转换为UTF-16BE(或LE)字节CharsetEncoder
:
CharsetEncoder encoder = Charset.forName("UTF-16BE").newEncoder(); ByteBuffer bytes = encoder.encode(CharBuffer.wrap(data)); // throws MalformedInputException
(如果你有字节,也可以使用CharsetDecoder
。)