222
    String s = "hello";
    String backup_of_s = s;
    s = "bye";

此时,备份变量仍然包含原始值“hello”(这是因为 String 的不变性吧?)。

但是用这种方法复制字符串真的安全吗(复制常规的可变对象当然不安全),还是写这个更好?:

    String s = "hello";
    String backup_of_s = new String(s);
    s = "bye";

换句话说,这两个片段之间有什么区别(如果有的话)?


编辑 - 第一个片段安全的原因:

让我根据已经提供的好的答案(主要集中在两个片段之间的性能差异问题)更详细地解释一下事情:

字符串在 Java 中是不可变的,这意味着 String 对象在构造后无法修改。因此,

String s = "hello";创建一个新的 String 实例并将其地址分配给s(s作为对实例/对象的引用)

String backup_of_s = s;创建一个新变量backup_of_s并对其进行初始化,使其引用当前所引用的对象s

注意:字符串不变性保证这个对象不会被修改:我们的备份是安全的

注2:Java垃圾回收机制保证这个对象只要被至少一个变量引用就不会被销毁(backup_of_s在这种情况下)

最后,s = "bye";创建另一个 String 实例(因为不可变性,这是唯一的方法),并修改s变量,以便它现在引用新对象。

4

5 回答 5

156

由于字符串是不可变的,因此两个版本都是安全的。然而,后者效率较低(它会创建一个额外的对象,并且在某些情况下会复制字符数据)。

考虑到这一点,应该首选第一个版本。

于 2012-05-15T20:04:52.053 回答
27

字符串是不可变的对象,因此您可以复制它们只是应对对它们的引用,因为引用的对象不能改变......

所以你可以像你的第一个例子一样复制没有任何问题:

String s = "hello";
String backup_of_s = s;
s = "bye";
于 2012-05-15T20:07:14.660 回答
10

您的第二个版本效率较低,因为它在根本不需要这样做时会创建一个额外的字符串对象。

不变性意味着您的第一个版本按照您期望的方式运行,因此是首选方法。

于 2012-05-15T20:05:45.640 回答
0

第二种情况在字符串池方面也是低效的,您必须在返回引用上显式调用 intern() 以使其成为实习生。

于 2014-04-14T06:59:54.100 回答
-14
String str1="this is a string";
String str2=str1.clone();

这样的副本怎么办?我认为获得一个新的副本更好,这样在以后的操作中引用和修改数据str1时不会受到影响。str2

于 2013-05-08T12:41:54.530 回答