class OtherObject {
String innerString;
OtherObject(String x) {innerString = x;}
}
class Playground {
public static void mutate(OtherObject toMutate) {
toMutate.innerString = toMutate.innerString.substring(toMutate.innerString.length()/2);
}
public static void mutate(String toMutate) {
toMutate = toMutate.substring(toMutate.length()/2);
}
public static void main(String[] args) {
String helloWorld = new String("Hello, World!");
OtherObject helloWorld2 = new OtherObject("Hello, World!");
mutate(helloWorld);
mutate(helloWorld2);
System.out.println(helloWorld);
System.out.println(helloWorld2.innerString);
}
}
在这个例子中,我通过方法 mutate
设置了两个对象并且只有一个对象发生了变化,如以下输出所示:
Hello, World!
World!
Process finished with exit code 0
这让我很困惑,因为如果我没记错的话:
- 对象在传递给方法时正在传递引用,因此即使不返回,对象本身也可以更改
- 这与我可以将 ArrayList 传递到方法中并对其进行操作而无需返回相同的 ArrayList 并将其分配给
main
中的前一个 ArrayList 的原因相同。 . - 字符串是一个对象。
为什么字符串 helloWorld 没有改变?
最佳答案
您似乎在问这个:
public static void mutate(String toMutate) {
toMutate = toMutate.substring(toMutate.length()/2);
}
toMutate
变量是一个局部变量,包含对字符串对象的引用。为其赋值仅会更改局部变量。它不会更改引用来源的调用方法中的变量。
技术上的答案是Java参数传递是“按值传递”而不是“按引用传递”。当您传递字符串时,您是按值传递字符串引用。您没有传递对调用者中保存字符串引用的变量的引用。在 Java 中你不能这样做。
简而言之,不可能用您似乎想要的语义在 Java 中实现 void mutate(String)
。方法签名需要不同,语义和用法也会不同。
Objects, when passed into methods are passing references, therefore even without returning, the object itself can be changed.
这是你的错误。一个对象可以被更改只要它被设计为可以更改。 String 对象是不可变的。它经过专门设计,因此您无法更改它。
如果您想要一个可以更改的 Java 中的“类似字符串”的对象,您可以使用 StringBuilder
或 StringBuffer
对象。 (有关详细信息以及它们之间的差异,请参阅 javadoc。)
关于java - 为什么本例中的字符串 helloWorld 没有改变?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36511974/