java - String.getBytes 是否被安全使用?

标签 java unicode utf-8 character-encoding jvm

目前,我需要在 Java 中处理字符串的字节,这引发了很多关于 JVM 的编码和实现细节的问题。我想知道我所做的是否有意义,或者是否多余。

首先,我了解到在运行时,String 中的 Java char 将始终表示 Unicode 中的符号。

其次,UTF-8编码总是能够成功编码Unicode中的任何符号。反过来,以下代码段将始终返回一个 byte[] 而不进行任何替换。 getBytes 文档是 here .

byte[] stringBytes = myString.getBytes(StandardCharsets.UTF_8);

然后,如果 stringBytes 以下列方式在不同的 JVM 实例中使用,它将总是产生一个等同于 myString 的字符串。

new String(stringBytes, StandardCharsets.UTF_8);

您认为我对getBytes 的理解正确吗?如果是这样的话,你会如何证明它的合理性?我是否遗漏了一个可能导致我无法获得等效版本的 myString 的病态案例?

提前致谢。


编辑:

您是否同意通过执行以下任何非异常流程都会导致处理案例,从而使我们能够成功地重建字符串?


编辑:

根据答案,这里有一个解决方案,它允许您在没有异常抛出时安全地重建字符串。您仍然需要以某种方式处理异常。

首先,使用编码器获取字节:

final CharsetEncoder encoder =
    StandardCharsets.UTF_8.
        .newEncoder()
        .onUnmappableCharacter(CodingErrorAction.REPORT)
        .onMalformedInput(CodingErrorAction.REPORT);


// It throws a CharacterCodingException in case there is a replacement or malformed string
// The given array is actually bigger than required because it is the internal array used by the ByteBuffer. Read its doc.
byte[] stringBytes = encoder.encode(CharBuffer.wrap(string)).array();

其次,使用编码器给出的字节构造字符串(非异常路径):

new String(stringBytes, StandardCharsets.UTF_8);

最佳答案

it will always yield a string equivalent to myString.

嗯,不是总是。这个世界上没有很多事情总是发生。

我能想到的一种极端情况是,当您调用 getBytes 时,myString 可能是一个“无效”字符串。例如,它可能有一个单独的代理对:

String myString = "\uD83D";

这种情况发生的频率在很大程度上取决于您使用 myString 做什么,所以我会让您自己考虑一下。

如果 myString 有一个单独的代理对,getBytes 会为它编码一个问号字符:

// prints "?"
System.out.println(
    new String(myString.getBytes(StandardCharsets.UTF_8), StandardCharsets.UTF_8)
);

我不会说 ? 与格式错误的字符串“等效”。

另请参阅:Is an instance of a Java string always valid UTF-16?

关于java - String.getBytes 是否被安全使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67584378/

相关文章:

qt - Qt中Utf-32字符的长度

java - 从扫描仪/控制台读取日语字符和字符串

java - 如何在Java 8中使用UTF-8字节的键打印trie的键

Xcode 不断猜测和解释错误的编码

Java HashSet 键/值对

java - 单击提交按钮时,我试图在文本框中生成随机数

java - 如何提高GPS坐标的精度?

java - 如何改善微服务之间的通信

ios - 检测用户是否在 UITextView 中输入了表情符号字符

php - 我想用 php 将西里尔字母发送到 mysqli 数据库