“return (string expr)”和“return New String(string expr)”有什么区别?

6
这两种方法有区别吗?
public String toString() {
    return this.from.toString() + this.to.toString();
}

public String toString() {
    return new String(this.from.toString() + this.to.toString());
}

(假设from.toString()to.toString()方法返回的是字符串。)基本上,我在Java中对于字符串处理感到困惑,因为有时候字符串被视为基本类型,尽管它们是类实例。

1
可能是字符串对象和字符串字面值之间的区别的重复问题。 - MarsAtomic
Jack,请在提问之前先进行谷歌和Stack Overflow搜索。通常情况下,你会发现问题已经被详细回答了。你的问题在SO上已经被多次回答过了。 - MarsAtomic
@jeppe,感谢您提供这个有趣的链接。所以这个问题并不是那么愚蠢 :) - jackthehipster
显示剩余5条评论
4个回答

5

实际上并没有区别。

因为你的两个函数都有返回类型String,创建一个新的String()只是额外的开销。这就像把一个字符串再次包装成一个字符串,并在池中创建一个新的字符串,实际上并没有任何优势。

但是基本类型和字符串对象之间的一个主要区别是,String类总是创建新的字符串。

String str = "my string";

如果“my string”已经存在于String pool中,则会使用相同的字符串而不是创建新的字符串。
这就是为什么当...
String str1= "my string";
String str2 ="my string";

str1==str2? --> will return true

以上代码的结果将为真,因为使用了字符串池中相同的字符串对象。
但是当您执行以下操作时:
String str = new String("new string");

无论字符串池中是否已存在相同的字符串对象,始终会创建一个新的字符串对象。

所以比较:

String str1 = new String("new string");
String str2 = new String("new string");

str1==str2 --> will return false

1
new String(String)并不会包装原始字符串。它只是创建了一个全新的(无用的)副本 - JB Nizet
假设(但不确定)Java内部也会为第一个方法创建某种对象,是吗?因此基本上在两种情况下都发生了相同的事情,只是在第一种情况下它是隐式发生的,在第二种情况下是显式发生的?编辑:不,当然第二次JVM也需要创建隐式对象,然后总共创建两个对象...好的,明白了。 - jackthehipster
1
不需要使用 new String(this.from.toString() + this.to.toString()),因为 this.from.toString() + this.to.toString() 已经是一个包含2000个字符的字符串对象。使用 new String(this.from.toString() + this.to.toString()) 会创建另一个包含2000个字符的字符串对象,这个对象与 this.from.toString() + this.to.toString() 中的字符数组相同。这样做没有任何意义:它会占用更多的内存,强制垃圾回收器工作更多,需要CPU时间来进行复制,并且返回的字符串值仍然相同。 - JB Nizet

3

有一个区别,如果你之前定义了一个字符串String "ABC"。Java会对字符串进行内部处理,因此当你没有明确声明需要一个new对象时,它将返回一个具有相同值的对象。例如:

String abc = "abc";

// Some code.

return new String("abc"); // This will be a new object.

如果你这样做:

String abc = "abc";

// Some code.

return "abc"; // This will be the above object.

这是因为JVM浪费内存来存储相同值的对象是没有意义的,所以它将它们存储在内存中,并等待您再次需要/使用它们! 你会选择哪一个? 往往情况下,字符串内部化过程不会对您造成太多影响,所以通常选择前者就可以了。

1
不,不是这样的。使用 new String(String) 是无用的,因为 String 是不可变的。String 的状态永远不会改变。此外,字符串驻留与 OP 的问题无关。 - JB Nizet
我读了开头,它是正确的,但我没有看到有关String状态的额外描述,第二次读时感到“啥?他在说什么?” 编辑后的答案是正确的。虽然OP并没有直接询问内部运作,但他询问了区别,而内部运作是主要区别。 - MarsAtomic
大多数人都同意,但这让我想知道:“更多时候,字符串内部化过程不会对你造成太大的影响”。你能举一个实际的例子,说明字符串内部化何时会“对你造成太大的影响”吗? - Jonik
我对这个问题采取了“永不放弃”的态度。 - christopher

2
第二种方法有额外的开销。在第二种方法中,你需要再次初始化字符串,而第一种方法不需要。类似这样:
String s = "something";

return s; 

vs

return new(s);

除此之外,两者都可以完成完全相同的任务。

1

return new String(this.from.toString() + this.to.toString());

上述语句将创建2个对象。
第一个对象是指向this.from.toString() + this.to.toString()连接值的对象。这没有引用。 第二个对象是由new运算符创建的。

return this.from.toString() + this.to.toString();

这将在堆内存区域创建1个对象。

这个对象的引用并不会被存储在字符串池区域中。 - JB Nizet

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