目前,我需要在 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)
);
我不会说 ?
与格式错误的字符串“等效”。
关于java - String.getBytes 是否被安全使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67584378/