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 的解决方案 - 请参阅 Effective Java 项“支持不变性”。
不过,如前所述,StringBuilder 通常会为您提供更好的性能 - 如果您有很多附加操作要做,尤其是在循环内,请使用 StringBuilder。
但是如果可以的话,尝试传递不可变的Strings 而不是可变的StringBuilders——你的代码会更容易阅读和维护。考虑将您的参数设置为final,并配置您的 IDE,以便在您将方法参数重新分配给新值时发出警告。