嗨,我正在学习我的scja考试,并且有一个关于字符串传递ref / value以及它们如何不可变的问题。以下代码输出“abc abcfg”。
我想知道的是为什么会发生这种情况?我不明白方法f里面发生了什么。字符串是按值传递的,所以它肯定会在方法中变为“abcde”吗?因为如果b + =“fg”附加到字符串,为什么它在方法中不起作用?
谢谢!
public class Test {
public static void main(String[] args){
String a =new String("abc");
String b = a;
f(b);
b+="fg"
System.out.println(a + " " + b);
}
public static void f(String b){
b+="de";
b=null;
}
}
答案 0 :(得分:8)
b+="de";
函数中的行void f(String b)
会创建一个String
的全新对象,该对象不会影响main
函数中的对象。
因此,当我们说String
不可变时,String
对象上的任何更改将导致创建一个全新的{{1对象
String
答案 1 :(得分:3)
这行代码:
b += "de";
大致翻译为:
b = b + "de";
创建一个新String并将其存储在局部变量'b'中。无论如何,该方法之外的参考不会改变。在尝试以这种方式理解其工作原理时,需要记住几个关键事项。
将新对象分配给传递给方法的变量时,只会替换本地堆栈中的地址,并创建新对象的地址。方法之外的实际对象地址保持不变。
答案 2 :(得分:2)
在方法f()
中,您要为参数b
分配一个新的String,但参数就像局部变量一样,因此为它们分配内容对方法之外的任何内容都没有影响。这就是为什么传入的字符串在方法调用后没有改变的原因。
答案 3 :(得分:0)
将String传递给方法时,它会在方法中创建一个新的String对象。如果在方法中放入println语句,如下所示:
public static void f(String b){
b+="de";
System.out.println(b);
b=null;
}
您会看到输出“abcde”。
但是,一旦您退出该方法,您将返回到原始对象,该对象尚未更改。因此,将fg附加到它只会产生一个新的字符串(b),其中包含“abcfg”。
答案 4 :(得分:0)
当你说b + =“de”
之类的东西时,你会创建一个新的String对象就像说b = new String(b +“de”);
如果你真的想保留传入的值,那么使用这样的stringBuilder:
StringBuilder a =new StringBuilder("abc");
StringBuilder b = a;
f(b);
b.append("fg");
System.out.println(a + " " + b);
}
public static void f(StringBuilder b){
b.append("de");
b=null;
}
现在你的输出将是“abcdefg”,因为stringbuilder对象b作为对象本身的值传递给f。我修改了值而没有使用“new”来指向另一个对象。希望现在清楚。