疯狂的JAVA讲义之5.2.2
JAVA方法的参数传递方式:值传递(将实际参数值的副本传入方法内,而参数本身不会收到影响)
一、基本类型的值传递
public class Test {
public static void main(String[] args) {
int a = 10;
int b = 20;
System.out.println("执行set方法前的a="+a+"----b="+b);
setAb(a,b);
System.out.println("执行set方法后的a="+a+"----b="+b);
}
public static void setAb(int a,int b){
System.out.println("set方法内部执行前 a="+a+"----b="+b);
int c = a;
a = b;
b = a;
System.out.println("set方法内部执行后 a="+a+"----b="+b);
}
}
运行结果:
执行set方法前的a=10----b=20
set方法内部执行前 a=10----b=20
set方法内部执行后 a=20----b=20
执行set方法后的a=10----b=20
证明了所谓的值传递就是将实际参数值的副本传入方法内,参数本身不会受到影响
main的栈区中有a ,b 2个变量;setAb时,将a,b的副本传入到setAb的栈区中,此时setAb的栈区中有a,b2个变量,在setAb方法内部进行值交换时,实际交换的是setAb栈区中的a,b变量。也就是main中的a,b和setAb中的a,b实际是不同的变量。借用书中的截图(a,b的值和方法名不同)
二、引用类型的值传递
基本类型的值传递不会改变,先撸一手引用类型的代码块,是不是值也不会替换?
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setName("张三");
System.out.println("main设置前的student:" + student);
setStudent(student);
System.out.println("main设置后的student:" + student);
}
public static void setStudent(Student student2) {
System.out.println("setStudent设置前的student:" + student2);
student2.setName("李四");
System.out.println("setStudent设置后的student:" + student2);
}
}
class Student {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
执行结果:
main设置前的student:Student{name='张三'}
setStudent设置前的student:Student{name='张三'}
setStudent设置后的student:Student{name='李四'}
main设置后的student:Student{name='李四'}
main里面的值也改成李四了?这说明引用类型和基本类型的参数不一样吗?然而引用类型的参数传递也是使用的值传递。
只不过引用类型的创建对象,会在内存中存在2个东西,堆内存中保存了new Student()出来的对象本身(实例),而栈内存中保存了引用该对象的引用变量。
student和stundent2这2个引用变量指向的地址都是堆内存中的Student对象。
执行student2.setName("李四");
实际就是将堆内存的Student对象的name设置成李四
所以main栈区和setStudent栈区两个设置后的student都是打印李四