程序设计语言中往往分成按值调用和按引用调用。按值调用(call by value)表示方法接收的是调用者提供的值。而按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。一个方法可以修改传递引用所对应的变量值,而不能修改传递值调用所对应的变量值。
在Java程序设计语言中,方法参数总是按值调用。方法得到的是参数值的一个拷贝。特别需要注意的是,方法不能修改传递给它的任何参数变量的内容(这句话下文会通过三个例子来进行分析)
首先需要知道的是,Java的方法参数共有两种类型:
- 基本数据类型
- 对象引用
例子代码1:
public class ClassA {
public static void testCallByValue(int x){
x++;
System.out.println("testCallByValue: "+x);
}
public static void main(String[] arg){
int y=1;
testCallByValue(y);
System.out.println("main: "+y);
}
}
输出:
testCallByValue: 2
main: 1
可以看到,y被传入testCallByValue(int x)
方法,参数x的值变为2,y本身的值依然为1,没有变化。
执行的具体过程如下:
- x被初始化为y值的拷贝(也就是1)
- x++,x的值变为2,y依然为1
- 方法结束,参数x不再使用
例子代码2:
public class ClassA {
public static void testCallByReference(List arrayListX){
arrayListX.add(10000);
arrayListX.add(10010);
arrayListX.forEach(array->System.out.println("testCallByReference: "+array));
}
public static void main(String[] arg){
List<Integer> arrayListY = new ArrayList<>();
arrayListY.add(10086);
testCallByReference(arrayListY);
arrayListY.forEach(array->System.out.println("main: "+array));
}
}
输出:
testCallByReference: 10086
testCallByReference: 10000
testCallByReference: 10010
main: 10086
main: 10000
main: 10010
可以看到arrayListY被传入testCallByReference(List arrayListX)
方法后,自身的值也发生了改变。
执行的具体过程如下:
扫描二维码关注公众号,回复:
4470710 查看本文章
- arrayListX被初始化为arrayListY值的拷贝,这里是一个对象的引用(即arrayListX和arrayListY引用的同一个对象)
testCallByReference(List arrayListX)
方法应用于这个对象的引用,add成功- 方法结束,参数arrayListX不再使用,arrayListY仍然引用着这个对象
例子代码3:
public class ClassA {
public static void testCallByReference(String strX){
strX = "strX";
System.out.println("testCallByReference: "+strX);
}
public static void main(String[] arg){
String strY = "strY";
testCallByReference(strY);
System.out.println("main: "+strY);
}
}
输出:
testCallByReference: strX
main: strY
可以看到strY被传入testCallByReference(String strX)
方法后,自身的值没有改变。
执行的具体过程如下:
- strX被初始化为strY值的拷贝,这里是一个对象的引用(即strX和strY引用的同一个对象)
testCallByReference(String strX)
方法使strX引用了一个新的字符串对象,strY不会改变自身的引用- 方法结束,参数strX不再使用,strY依然引用着
"strY"
这个对象
上面三个例子各做一个结论说明,分别是:
- 一个方法不能修改一个基本数据类型参数的值
- 一个方法可以改变一个对象参数的状态
- 一个方法不能让对象参数引用一个新的对象