After running the code below I get this output: Eve 1200
Could anyone explain me why the value of Person type variable is being changed and value of Integer type variable is not? I have already read this:
- www.javaworld.com/javaworld/javaqa/2000-05/03-qa-0526-pass.html
- www.yoda.arachsys.com/java/passing.html#formal
but I don't get why with Person and Integer types it works different.
public class Test {
public static void main(String[] args) {
Object person = new Person("Adam");
Object integer = new Integer("1200");
changePerson(person);
changeInteger(integer);
System.out.pr开发者_如何学运维intln(person);
System.out.println(integer);
}
private static void changeInteger(Object integer) {
integer = 1000;
}
private static void changePerson(Object person) {
((Person)person).name="Eve";
}
}
In Java, primitive types (such as integer) are always handled exclusively by value, and objects (such as your Person) and arrays are always handled exclusively by reference.
If you pass a primitive the value will be copied, if you pass a reference type the address will be copied, hence the differences.
If you follow those links above and/or do a bit of googlin' you'll find out more.
In the Integer
case, you're changing the value of the parameter itself (which is local to the method). In the Person
case, you're changing the value of a field inside the parameter. That field is part of the object, and so it's visible to the caller.
In changeInteger()
when you do integer = 1000 a new object is created and assigned a local variable integer.
So if you do
person = new Person();
person.name="Eve";
in changePerson()
you will get the same behavior as for integer.
PS: The old references are lost once you assign it to newly created objects inside the function.
Just for any future reference,the accepted answer isn't the correct answer in this case (although the links do provide enough informaiton to get the correct answer). The OP problem has nothing to do with primitves vs objects. In the exampe code given, there are no primitives used, both integer and person are full objects. Answers below that answer are more helpful. The key is that the parameter variable (i.e. the variable used to store the passed in parameter in the methods) is given the current value of variable used in the method call. Objects are stored by reference in Java, so they point to the object rather than storing the object directly. So the parameter variable in the method is given this pointer address and uses this to access the object details. So if the method changes the object, this is the same object that the calling code is pointing towards and so both places will see the change. In the integer example, when you say integer = 1000, it is overwriting the passed in pointer with a new pointer to a new Integer object - you have lost the connection to the original object.
Note that is no way to change an Integer object once it has been created (e.g. no .setValue() method) so there is no way to write the code in a way that could change the original Integer object.
In changePerson() you change the given object itself via his public name property. In changeInteger() you change the local Integer Object;
Put a System.out.println(integer); inside the changeInteger() function and you will see, that the Integer changes, but only in function scope..
private static void changeInteger(Object integer) {
integer = 1000;
System.out.println(integer);
}
In the changeInteger()
method you are assigning a completely new object (1000) to the reference variable integer
. But the reference variable integer
in the main()
method still points to the old object (1200). Thus the print() statement in the main() method prints the old value (1200)
However, in the changePerson()
method the reference variable person
still points to the old object. Just that a value of one of its field is being change.
Aslo, do keep in mind that Integer (and so are other primitive wrappers) mutable. Any time you need to assign a new value to the ref var, JDK will create a whole new object.
Hope this helps!
Your code below compiles? It needs a cast.
private static void changeInteger(Object integer) {
integer = 1000;
}
Your integer
will be changed if it was embedded in another object
e.g. Person
.
EDIT :
Wrong on the compilation issue. In Java, references are copied by value. So in first case the reference get pointed to different memory. In the second case, name
comes as part of Person
. Since you are changing name through Person
without changing Person
, change in name
is reflected outside method. Hope this helps.
精彩评论