通过引用/值传递的 Java 字符串不可变
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14916520/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Java String immutable passed by reference/value
提问by Taobitz
Hi Im studying for my scja exam and have a question about string passing by ref/value and how they are immutable. The following code outputs "abc abcfg".
嗨,我正在为我的 scja 考试而学习,并且有一个关于通过 ref/value 传递的字符串以及它们如何不可变的问题。以下代码输出“abc abcfg”。
What I want to know is why is this happening? Im not understanding what happens inside of method f. String is passed by value so surely it should change to "abcde" inside the method? Because if b+="fg" appends to the string why doesnt it work inside the method?
我想知道的是为什么会这样?我不明白方法 f 内部发生了什么。字符串是按值传递的,所以它肯定应该在方法内更改为“abcde”?因为如果 b+="fg" 附加到字符串为什么它在方法中不起作用?
Thanks!
谢谢!
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;
}
}
采纳答案by Bohemian
In your method f()
you are assigning a new String to the parameter b
, but parameters are just like local variables, so assigning something to them has no effect on anything outside the method. That's why the string you passed in is unchanged after the method call.
在您的方法中,f()
您正在为参数分配一个新的 String b
,但参数就像局部变量一样,因此为它们分配一些东西对方法之外的任何内容都没有影响。这就是为什么你传入的字符串在方法调用后没有改变的原因。
回答by iTech
The line b+="de";
in the void f(String b)
functions creates a completely new object of String
that does not affect the object in the main
function.
函数b+="de";
中的这一行void f(String b)
创建了一个String
不影响main
函数中对象的全新对象。
So when we say String
is immutablewhen mean anychange on a String
object will result in creating a completely new String
object
因此,当我们说String
是不可变的时,意味着对对象的任何更改String
都将导致创建一个全新的String
对象
public class Test {
public static void main(String[] args){
String a =new String("abc");
String b = a; // both a & b points to the same memory address
f(b); // has no effect
// b still has the value of "abc"
b+="fg" // a new String object that points to different location than "a"
System.out.println(a + " " + b); // should print "abc abcfg"
}
public static void f(String b){
b+="de"; // creates a new object that does not affect "b" variable in main
b=null;
}
}
回答by Perception
This line of code:
这行代码:
b += "de";
Roughly translates to:
大致翻译为:
b = b + "de";
Which creates a new String and stores it in the local variable 'b'. The reference outside the method is not changed in anyway by this. There are a couple of key things to remember when trying to understand how/why this works this way.
它创建一个新字符串并将其存储在局部变量“b”中。无论如何,方法外部的引用不会因此而改变。在尝试了解如何/为什么以这种方式工作时,需要记住一些关键的事情。
- In Java, all method arguments are passed by value.
- Methods have a local stack where all their data is stored, including the method arguments.
- 在 Java 中,所有方法参数都是按值传递的。
- 方法有一个本地堆栈,其中存储了它们的所有数据,包括方法参数。
When you assign a new object to a variable that was passed into a method, you are only replacing the address in the local stack, with the address of the new object created. The actual object address outside of the method remains the same.
当您将新对象分配给传递给方法的变量时,您只是将本地堆栈中的地址替换为创建的新对象的地址。方法外的实际对象地址保持不变。
回答by Andrew Martin
When you pass the String into the method, it creates a new String object in the method. If you put a println statement in your method, like this:
当您将 String 传递给该方法时,它会在该方法中创建一个新的 String 对象。如果在方法中放入 println 语句,如下所示:
public static void f(String b){
b+="de";
System.out.println(b);
b=null;
}
You would see the output "abcde".
您会看到输出“abcde”。
However, once you come out of the method, you go back to your originalobject, which has not been altered. Therefore, appending fg to it will only produce a NEW string (b), containing "abcfg".
但是,一旦退出该方法,您将返回到未更改的原始对象。因此,将 fg 附加到它只会产生一个新的字符串 (b),其中包含“abcfg”。
回答by j2emanue
Your creating a new object of String when you say something like b+="de"
当您说 b+="de" 之类的内容时,您会创建一个新的 String 对象
Its like saying b = new String(b+"de");
就像说 b = new String(b+"de");
If you really want to keep the value passed in then use a stringBuilder like this:
如果您真的想保留传入的值,请使用像这样的 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;
}
Now your output will be "abcdefg" because stringbuilder object b was passed into f as the value of the object itself. I modified the value without using "new" to point to another object. Hope its clear now.
现在您的输出将是“abcdefg”,因为 stringbuilder 对象 b 作为对象本身的值被传递到 f 中。我修改了该值而没有使用“new”来指向另一个对象。希望现在清楚了。