Java字符串编码(UTF-8)

18

我遇到了这一行旧代码,现在正在试图搞清它的含义:

String newString = new String(oldString.getBytes("UTF-8"), "UTF-8"));

就我所理解的,它使用相同的字符集进行编码和解码。

这与以下内容有何区别?

String newString = oldString;

这两行代码是否存在任何情况下会有不同的输出?

p.s.:仅澄清一下,我知道Joel Spolsky在编码方面的卓越文章!


8
当使用String newString = oldString;时,唯一的区别当然是您仍然只有一个字符串副本(您只是从两个变量指向它)。而解码/编码则会制作字符串的副本。尽管String是不可变的,但这并不重要。可能这不是旧代码编写方式的原因;String有一种更直接的方法可以克隆自己(String(String))。我想不到除了测试String类的编码/解码方法之外,为什么会有一个好的理由让您执行编码/解码操作。 - T.J. Crowder
上下文是否提供了任何提示,为什么可能需要或已经需要字符串转换? - Thorbjørn Ravn Andersen
@T.J.Crowder:+1,当然!我并不是指实际对象的差异。谢谢你指出来。 - OceanBlue
还有一个主要的区别:其中一个无法编译 ;-) - Draško Kokić
2个回答

22

这可能是一种复杂的做法

String newString = new String(oldString);

当字符串的底层char[]比实际使用的要长时,这会缩短字符串。

然而,更具体地说,它将检查每个字符是否可以进行UTF-8编码。

在字符串中有一些无法进行编码的“字符”,它们将被转换为?

位于\uD800和\uDFFF之间的任何字符都无法编码,并将被转换为“?”

String oldString = "\uD800";
String newString = new String(oldString.getBytes("UTF-8"), "UTF-8");
System.out.println(newString.equals(oldString));
打印
false

2
oldString 无法进行正确编码的唯一原因是它本身不是有效的 UTF-16(Java 中字符串的本地表示)字符串。UTF-8 完全能够对任何 Unicode 代码点进行编码。在这种情况下,只有当 oldString 包含无效的 UTF-16 字节序列时才会有差异。 - Cagatay

4
这与以下代码有何不同?
这行代码:
String newString = new String(oldString.getBytes("UTF-8"), "UTF-8"));

构造一个新的字符串对象(即oldString的副本),而这行代码:

String newString = oldString;

声明一个新的java.lang.String类型变量,并将其初始化为引用与变量oldString相同的字符串对象。

是否存在任何情况下这两行代码会有不同的输出结果?

完全有可能:

String newString = oldString;
boolean isSameInstance = newString == oldString; // isSameInstance == true

对比。

String newString = new String(oldString.getBytes("UTF-8"), "UTF-8"));
 // isSameInstance == false (in most cases)    
boolean isSameInstance = newString == oldString;

a_horse_with_no_name(见评论)是正确的。等同于

String newString = new String(oldString.getBytes("UTF-8"), "UTF-8"));

String newString = new String(oldString);

与彼得·劳瑞在他的回答中解释的编码微小差异相比,减去它。


String newString = new String(oldString) 相当于“原始”的那行代码,我想。 - user330315

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接