形参:是指在定义函数时使用的参数,目的是用于接收调用该函数时传入的参数。简单理解,就是所有函数(即方法)的参数都是形参。
实参:在调用有参函数时,主调函数和被调函数之间有数据传递关系。在主调函数中调用一个函数时,函数名后面括号中的参数称为“实际参数”。
实参将数据传递给形参的方式:
- 按值传递
- 按引用传递
按值传递:指在调用函数时,将实际参数复制一份传递给函数,这样在函数中修改参数时,不会影响到实际参数。其实,就是也就是说值在传递时,只会改变形参,不会改变实参。(基本数据类型)
按引用传递:是指在调用函数时,将实际参数的地址传递给函数,这样在函数中对参数的修改,将影响到实际参数。(引用数据类型)
当参数是基本数据类型时,数据不占用堆内存,按值传递
当参数是引用类型时,数据占用堆内存,按引用传递
例如:
public class Test2 {
public static void main(String[] args) {
int a = 10;
jisuan1(a);
System.out.println(a);//按值传递
int[] b = {1,2,3};
jisuan2(b);
System.out.println(b[0]);//按引用传递
}
public static void jisuan1(int a){
a = 20;
}
public static void jisuan2(int[] b){
b[0] = 100;
}
}
结果:
按值传递的数据不占堆内存,实参将数据传递给形参时只给形参一个复制的副本,形参对副本进行改变并不影响原实参的值,所以值传递改变形参不影响实参 。
提问:引用传递会改变原实参数组值的数据地址吗?
我们来检查一下调用方法前和调用方法后数组值的数据地址
public class Test2 {
public static void main(String[] args) {
int[] b = {1,2,3};
System.out.println(b);//调用方法前
jisuan2(b);
System.out.println(b);//调用方法后
}
public static void jisuan2(int[] b){
b[0] = 100;
}
}
结果:
我们发现改变前后b数组的数据地址没有发生改变
结论:引用数据传递的不是真正的数据地址,是引用的堆内存中的地址,无论引用传递的数据怎么改变,它也只是引用的堆内存中的地址,原数据组的数据地址并没有被改变,改变那部分的值只是形参复制给实参使用的的地址,并不是把原地址改变。
总结:
- 值传递不是简单的把实参传递给形参,而是,实参建立了一个副本,然后把副本传递给了形参,所以形参改变并不会影响到实参
- 在函数中,只有修改了实参所指向的对象内容,也就是引用堆内存中的地址,才会影响到实参。