前言
在写代码过程中,我们经常会调用方法并且传递参数,参数可能是基本数据类型
也可能是对象引用
,就像updateHeightAndPrint(int height,Student student)
方法这样,height
是基本数据类型
而student
是对象引用。好像既有按值调用又有按引用调用 (•_•)?
public void updateHeightAndPrint(int height,Student student){
height+=height;
System.out.println("Student:"+student.toString());
}
复制代码
真相只有一个
java程序设计语言总是采用按值调用
概念
- 按值调用(call by value):表示方法接收的是调用者提供的值。
(复制一份数据操作,不会影响到实际参数)
- 按引用调用(call by reference):表示方法接收的是调用者提供的变量地址。
(直接操作源文件,会影响到实际参数)
注意俩者的区别
:按值调用是“参数副本”(基本数据类型传递的是值的拷贝
,对象传递的是引用的拷贝
,都是拷贝后的副本),按引用调用 直接操作“源文件”。
传递基本数据类型的栗子
public static void main(String[] args) {
int a = 10;
int b = 10;
increaseAndPrint(a,b);
System.out.println("调用increaseAndPrint()后:a:"+a+",b:"+b);
}
/**
* 增加5并打印输出
*/
public static void increaseAndPrint(int c,int d){
c = c + 5 ;
d = d + 5 ;
System.out.println("cIncreaseResult:"+c+",dIncreaseResult:"+d);
}
复制代码
结果为:
increaseAndPrint()
方法调用过后,int a,b
的值还是10,可以得出一个方法不可能修改一个基本数据类型的参数
。(注意:在调用过程中c被初始化为a值的一个拷贝,d被初始化为b值的一个拷贝,重要的事情多三遍,传递的是值的拷贝、值的拷贝、值的拷贝
)
传递对象引用的栗子
public static void main(String[] args) {
Student wali = new Student("wali", 170);
Student jack = new Student("jack", 180);
increaseHeight(wali,jack);
System.out.println("wali:"+wali.toString()+",jack:"+jack.toString());
}
public static void increaseHeight(Student w,Student j){
w.setHeight(w.getHeight()+10);
j.setHeight(j.getHeight()+10);
}
复制代码
结果:
可以看到改变一个对象参数状态的方法并不是一件难事。理由很简单,方法得到的是对象引用的拷贝
。方法在运行过程中,w为wali对象引用的拷贝,j为jack对象引用的拷贝,也就是说w和wali、j和jack这俩个引用指向的是同一个对象
,所以在w.setHeight(w.getHeight()+10)
执行后wali对象的height属性变更了,而当方法结束后,w和j都不在使用,当然wali和jack继续引用那个Height被增加了10的对象。
举个反栗阐述,对象引用是按值传递的,也就是说操作的是拷贝,而不是原文件
public static void main(String[] args) {
Student wali = new Student("wali", 170);
Student jack = new Student("jack", 180);
swap(wali,jack);
System.out.println("交换后wali:"+wali.toString()+",jack:"+jack
.toString());
}
public static void swap(Student w,Student j){
Student temp=w;
w=j;
j=temp;
System.out.println("swap中:");
System.out.println("wali:"+w.getName());
System.out.println("jack:"+j.getName());
}
复制代码
结果:
如果java采用的是引用传递那么调用这个方法就应该能够改变wali和jack引用。然后结果并不是我们想象的那样。最终白费力气,在方法结束时w和j被丢弃。原来的变量wali和jack仍然引用方法调用之前所引用的对象。
总结
- 一个方法不能修改一个基本数据类型的参数(即数值型,或布尔值)
- 一个方法可以改变一个对象的参数的状态
- 一个方法不能让对象参数引用一个新的对象。
写在最后
谢谢各位掘友耐心的看到这里,如有错误请多多指教。欢迎在评论区共同探讨问题。感谢!感谢!感谢!