Java 字符串的实例是否总是有效的 UTF-16?
Is an instance of a Java string always valid UTF-16?
对于任何给定的 Java 字符串 s
,我想知道 s
表示的字符数组是否 保证 到是有效的 UTF-16 字符串,例如:
final char[] ch = new char[s.length()];
for (int i = 0; i < ch.length; ++i) {
ch[i] = s.charAt(i);
}
// Is ch guaranteed to be a valid UTF-16 encoded string?
如果不是,有哪些生成无效 UTF-16 的简单 Java 语言测试用例?
编辑:有人将问题标记为 [ 的可能重复 我只能说,String
和a char[]
以及为什么前者至少在理论上可以保证其内容而后者没有的原因。我不是在问关于数组的问题,我是在问关于 String
s.
的问题
不,Java 字符串的实例不能保证在程序执行期间的所有点都包含有效的 UTF-16 代码单元序列(即 16 位值)。它也确实必须以这种方式工作。
这很容易证明。假设您有一系列代码点(它们是通常存储在 32 位整数中的 21 位数量),您希望将其附加到字符串,一次一个字符单元。如果其中一些代码点位于基本多语言平面之上(即,值 > 0xFFFF,因此需要超过 16 位来保存它们),那么在一次添加 16 位代码单元时,您将得到一个点在此期间,String 只有前导代理项,但还没有所需的尾随代理项。
换句话说,它的工作方式更像是一个字符单元缓冲区——一个 16 位值的缓冲区——而不是合法的 UTF-16 序列。这确实是 String 类型的必要方面。
只有在将其转换为特定编码时才会出现任何问题,因为不匹配、翻转或单独的代理项在三种 UTF 形式中的任何一种都是不合法的,因此编码器将无法表示它们。
没有。 String
只是 char[]
:
的无限制包装
char data[] = {'\uD800', 'b', 'c'}; // Unpaired lead surrogate
String str = new String(data);
要测试 String
或 char[]
的格式正确的 UTF-16 数据,您可以使用 CharsetEncoder
:
CharsetEncoder encoder = Charset.forName("UTF-16LE").newEncoder();
ByteBuffer bytes = encoder.encode(CharBuffer.wrap(str)); // throws MalformedInputException
对于任何给定的 Java 字符串 s
,我想知道 s
表示的字符数组是否 保证 到是有效的 UTF-16 字符串,例如:
final char[] ch = new char[s.length()];
for (int i = 0; i < ch.length; ++i) {
ch[i] = s.charAt(i);
}
// Is ch guaranteed to be a valid UTF-16 encoded string?
如果不是,有哪些生成无效 UTF-16 的简单 Java 语言测试用例?
编辑:有人将问题标记为 [String
和a char[]
以及为什么前者至少在理论上可以保证其内容而后者没有的原因。我不是在问关于数组的问题,我是在问关于 String
s.
不,Java 字符串的实例不能保证在程序执行期间的所有点都包含有效的 UTF-16 代码单元序列(即 16 位值)。它也确实必须以这种方式工作。
这很容易证明。假设您有一系列代码点(它们是通常存储在 32 位整数中的 21 位数量),您希望将其附加到字符串,一次一个字符单元。如果其中一些代码点位于基本多语言平面之上(即,值 > 0xFFFF,因此需要超过 16 位来保存它们),那么在一次添加 16 位代码单元时,您将得到一个点在此期间,String 只有前导代理项,但还没有所需的尾随代理项。
换句话说,它的工作方式更像是一个字符单元缓冲区——一个 16 位值的缓冲区——而不是合法的 UTF-16 序列。这确实是 String 类型的必要方面。
只有在将其转换为特定编码时才会出现任何问题,因为不匹配、翻转或单独的代理项在三种 UTF 形式中的任何一种都是不合法的,因此编码器将无法表示它们。
没有。 String
只是 char[]
:
char data[] = {'\uD800', 'b', 'c'}; // Unpaired lead surrogate
String str = new String(data);
要测试 String
或 char[]
的格式正确的 UTF-16 数据,您可以使用 CharsetEncoder
:
CharsetEncoder encoder = Charset.forName("UTF-16LE").newEncoder();
ByteBuffer bytes = encoder.encode(CharBuffer.wrap(str)); // throws MalformedInputException