Java方法的传参问题
首先贴一段代码
public class Test01 {
public static void main(String[] args) {
Student studentA= new Student("张三",12);
Student studentB= new Student("李四",12);
int a=0;
String str="原字符串";
update(a,str,studentA,studentB);
System.out.println(a);
System.out.println(str);
System.out.println(studentA);
System.out.println(studentB);
}
public static void update(int a,String str,Student student01,Student student02){
a=1;
str="修改后的字符串";
student01.setName("小三");
student01.setAge(13);
student02=new Student("小四",13);
}
public static class Student{
String name;
int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
}
正确答案
则main方法正确的输出答案是:
0
原字符串
Student{name='小三', age=13}
Student{name='李四', age=12}
而我犯的错误,就是以为str经过update方法后,会由"原字符串"变成"修改后的字符串"。
经过自己查找资料学习后,我知道java方法的传参分为值传递和引用传递。值传递就如同update方法里面的int a参数,八大基础类型的参数是属于值传递;引用传递就如同update方法里面的string类型参数和student对象,当参数是引用类型时,就属于引用传递。
接下来开始对这段代码的结果进行解析
str经过update方法后为什么没有产生变化?
引用类型作为参数时,是属于引用传递。引用传递会传递原对象的地址值,但是注意:传递的地址值只是一个副本。
当str进入方法重新赋值之前,方法内部的局部变量str的地址是509。
当str在方法内部变为“修改后的字符串”时,地址值已经变成了515,但是此时方法外的str(全局变量)依然指向的是509。当方法结束,局部变量就会被回收。然后输出语句输出的是地址值为509的str的值。
同样的道理,方法内的两个对象,为何studentA的姓名和年龄被改变了,而studentB的没有发生变化呢?
当student01调用setName()和setAge()这两个方法时,使用的地址值与studentA相同。相当于student01(局部变量)与studentA(全局变量)共用同一个实例。
但是局部变量student02使用了new,指向了一个新的实例,新的地址值。从此student02与studentB再无半分瓜葛,student02无论发生什么变化,都与全局变量student02无关了。