下面通过一个很经典的例子去理解java关于值的传递里面的细节
class Person{
String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Person(String name){
this.name = name;
}
}
public class TransferValueDemo {
public void changeInt(int i){
i = 30;
}
public void changeName(Person person){
person.setName("n2");
}
public void changeString(String string){
string = "str2";
}
public static void main(String[] args) {
int i = 20;
Person person = new Person("n1");
String str = "str1";
TransferValueDemo transferValueDemo = new TransferValueDemo();
transferValueDemo.changeInt(i);
transferValueDemo.changeName(person);
transferValueDemo.changeString(str);
System.out.println(i);
System.out.println(person.getName());
System.out.println(str);
}
}
运行结果
20
n2
str1
在changeInt中,java基本类型是存储在栈里面的,changeInt方法中传递的那个i,相当于拷贝了一份main方法中的i,并且把拷贝出来的副本传递给changeInt,因此在changeInt中对i进行修改,其实只是对副本进行修改,并不会影响到main方法中的那个i。
而在changeName中,传递的是person这个对象的引用,main方法中的引用a与changeName中的引用b指向同一个内存地址,他们获取到的是同一个对象,因此,调用对象的setName方法,修改了对象的属性后。在main方法中打印对象的name时候,会发现name改变了,因为main中指向的那个person对象的name属性的确是被修改了。
而在changeString中,传递的也是str这个对象的引用,但是不同的是,在给str赋予新值的时候,由于string类的特性,不会在原本对象上作出修改,而是会新建一个对象,并changeString中的引用b指向新的对象,因此,main中引用a依旧指向值为“str1”这个对象,然而changeString方法中的引用b,却是指向了一个值为“str2”的对象,也就是说,此时main中的引用与changeString中的引用指向的是不同的对象。当打印main中的str对象时,输出的是“str1”。