【问题标题】:Java char to bytes and back is converted wrongly (UTF-8)Java char 到字节并返回错误地转换(UTF-8)
【发布时间】:2020-06-01 09:18:10
【问题描述】:

在编程时,我遇到了字符串转换为字节然后再次返回字符串的奇怪行为。一些字符转换错误,因此字符串的hashCode 也发生了变化。字符串的长度保持不变。 从 55296 到 57343(U+D800 到 U+DFFF)的字符似乎会出现问题。其他字符工作正常。是因为他们是代理人吗?

String string = new String(new char[] { 56000 });
System.out.println((int)string.charAt(0));
System.out.println((int)new String(string.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8).charAt(0));

控制台输出为:

56000
63

这里发生了什么?这是一个java错误,还是我误解了什么?

【问题讨论】:

  • 长度为 1 的 String 的 hashCode 只不过是它本身的 char。我在问题中替换了它。
  • 您为什么要进行这些转换?字符串不是二进制数据的容器。对所有内容都使用字节数组。
  • 加密/解密必须使用字符串。如果字符串格式错误,我现在将抛出异常。

标签: java string encoding


【解决方案1】:

这是因为这些值不是字符而是代理项。其中两个值形成代理对,而代理对又代表一个字符。如果您只有一个低或高代理值,则这是无效编码而不是字符。

由于这是一个无效的编码,它被替换为“?”将其转换为 UTF-8 时的字符。

您可以在这里阅读更多信息,例如https://en.wikipedia.org/wiki/UTF-16

【讨论】:

  • 但是为什么string.getBytes(UTF_8) 是一个单字节数组呢?另一个去哪儿了?
  • 有趣的行为!所以java期望一个代理有一个后续的字符,否则编码错误。
猜你喜欢
  • 2011-08-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
  • 2013-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多