This question already has an answer here:
Beginner java question, but I cannot understand how call-by-Value ( or Reference ) is working in the example below -
How come the String value is not modified after it exits the method while my custom String Object is. ? Same with other classes like Date..
public class StringMadness {
public static void main(String[] args) {
String s = "Native String";
CustomStringObject cs = new CustomStringObject();
System.out.println("Custom String Before: " + cs.str);
hello(cs);
System.out.println("Custom String After: " + cs.str);
System.out.println("Native String Before: " + s);
hello(s);
System.out.println("Native String After: " + s);
}
private static void hello(String t) {
t = "hello " + t;
}
private static void hello(CustomStringObject o) {
o.str = "hello " + o.str;
}
}
class CustomStringObject {
String str = "Custom String";
}
Compare these two methods:
private static void hello(String t) {
t = "hello " + t;
}
private static void hello(CustomStringObject o) {
o.str = "hello " + o.str;
}
In the first case, you're assigning a new value to t
. That will have no effect on the calling code - you're just changing the value of a parameter, and all arguments are passed by value in Java.
In the second case, you're assigning a new value to o.str
. That's changing the value of a field within the object that the value of o
refers to. The caller will see that change, because the caller still has a reference to that object.
In short: Java always uses pass by value, but you need to remember that for classes, the value of a variable (or indeed any other expression) is a reference, not an object. You don't need to use parameter passing to see this:
Foo foo1 = new Foo();
Foo foo2 = foo1;
foo1.someField = "changed";
System.out.println(foo2.someField) // "changed"
The second line here copies the value of foo1
into foo2
- the two variables refer to the same object, so it doesn't matter which variable you use to access it.
There's an important difference between the two methods: using hello(String)
you're trying to change the reference to the String
, and with hello(CustomObject)
, given a reference, you're using the reference to change a member of the object.
hello(String)
takes a reference to a String
. In the function you're trying to change which object that reference points to, but you're only changing the pass-by-value copy of the reference. So your changes aren't reflected outside the method.
hello(CustomObject)
is given a copy of a reference to an object, which you can then use to change the actual object. Think of this as changing the contents of the object. So your changes are reflected in the caller.
Given a reference to an object, you can change the object using it's exposed methods/fields
Because for the String you are just changing the local parameter reference.
t
will point to new object and scoped to method only, so changes not visible outside.
Second case, the value you are changing will be updated to object,so those changes are visible after method call.
Doesn't work because String is an immutable object
来源:https://stackoverflow.com/questions/11801554/java-object-state-does-not-change-after-method-call