我习惯于在C
中执行以下操作
void main() {
String zText = "";
fillString(zText);
printf(zText);
}
void fillString(String zText) {
zText += "foo";
}
输出结果为:
foo
然而,在Java中,这似乎不起作用。我假设是因为String
对象是复制的,而不是通过引用传递的。我认为字符串是对象,它们总是通过引用传递。
这里发生什么事情?
发布于 2009-08-13 08:32:24
发生的情况是通过值传递引用,即传递引用的副本。java中的任何东西都不是通过引用传递的,因为字符串是不可变的,所以赋值创建了一个新的字符串对象,引用的副本现在指向该对象。原始引用仍然指向空字符串。
这对于任何对象都是一样的,即在方法中将其设置为新值。下面的例子让事情变得更加明显,但是连接一个字符串实际上是一回事。
void foo( object o )
{
o = new Object( ); // original reference still points to old value on the heap
}
发布于 2009-08-13 08:26:57
java.lang.String是不可变的。
我讨厌粘贴URL,但是如果你在java环境中,https://docs.oracle.com/javase/10/docs/api/java/lang/String.html对于你阅读和理解是必不可少的。
发布于 2009-08-13 08:43:12
Java中的所有参数都是通过值传递的。当您将String
传递给函数时,传递的值是对String对象的引用,但是您不能修改该引用,并且底层的String对象是不可变的。
作业
zText += foo;
等同于:
zText = new String(zText + "foo");
也就是说,它(在本地)将参数zText
重新分配为一个新的引用,该引用指向一个新的内存位置,其中是一个新的String
,其中包含zText
的原始内容,并附加了"foo"
。
原始对象不会被修改,并且main()
方法的局部变量zText
仍然指向原始(空)字符串。
class StringFiller {
static void fillString(String zText) {
zText += "foo";
System.out.println("Local value: " + zText);
}
public static void main(String[] args) {
String zText = "";
System.out.println("Original value: " + zText);
fillString(zText);
System.out.println("Final value: " + zText);
}
}
打印:
Original value:
Local value: foo
Final value:
如果你想修改这个字符串,你可以使用StringBuilder
或者其他一些容器(一个数组或者一个AtomicReference
或者一个自定义容器类)来提供一个额外级别的指针间接性。或者,只需返回新值并对其赋值:
class StringFiller2 {
static String fillString(String zText) {
zText += "foo";
System.out.println("Local value: " + zText);
return zText;
}
public static void main(String[] args) {
String zText = "";
System.out.println("Original value: " + zText);
zText = fillString(zText);
System.out.println("Final value: " + zText);
}
}
打印:
Original value:
Local value: foo
Final value: foo
在一般情况下,这可能是最类似于Java的解决方案--请参阅有效的Java项目“偏好不变性”。
正如前面提到的,StringBuilder
通常会给您带来更好的性能--如果您有很多附加操作要做,尤其是在循环中,那么可以使用StringBuilder
。
但是,如果可以的话,尝试传递不变的Strings
而不是可变的StringBuilders
--您的代码将更容易阅读和维护。考虑将参数设置为final
,并将集成开发环境配置为在将方法参数重新赋值为新值时发出警告。
https://stackoverflow.com/questions/1270760
复制相似问题