首先,什么是形参和实参?
- 形参:方法被调用时用于接收实参值的变量
- 实参:调用方法时的参数
例如:
public static void main(String[] args) {
int a = 0;
fun(a); //这里的参数a称为实参
}
public void fun(int a){ //这里的参数a称为形参
a = 1;
}
参数传递分为值传递和引用传递:
- 值传递:将变量的值复制一份传递给形参,传递的是复制的一份,对副本修改并不会影响原值
- 引用传递:将变量的地址传递给形参
Java为什么只有值传递,没有引用传递?
首先Java基本数据类型局部变量和值都是保存在栈中,而引用数据变量存储在栈中,实际的值存储在堆中,而栈中存储的实际是堆中值的地址
1、Java传递基本数据类型的参数
public static void main(String[] args) {
int a = 0; //基本数据类型
fun(a);
System.out.println(a); //0
}
public void fun(int a){
a = 1;
System.out.println(a); //1
}
此时是将栈中变量的值复制一份值传递给方法的形参,此时对复制后值操作并不会影响到原变量的值
1、Java传递引用数据类型的参数
- 传递数组引用数据类型参数:
public static void main(String[] args) {
int a[] = new int[2]; //引用数据类型
a[0] = 0;
fun(a);
System.out.println(a[0]); //1
}
public void fun(int[] a){
a[0] = 1;
System.out.println(a[0]); //1
}
当实参为数组时,属于引用数据类型的参数,此时是实参复制一份值传递给形参,不过实参和形参数组存储的值都为堆中的值的地址,所以对形参所指地址的a[0]改变相当于将实参数组的a[0]改变
- 传递String引用数据类型参数:
public static void main(String[] args) {
String a = new String("aaa"); //引用数据类型
fun(a);
System.out.println(a); //aaa
}
public void fun(String a){
a = "bbb";
System.out.println(a); //bbb
}
String类型也属于引用数据类型为什么此时对形参改变不影响实参的改变?
首先实参传递的还是String的在堆中值复制的地址值,但是String是static final修饰的,也就是不可变的,当对String类型的值修改时,相当于重新new String("bbb")的值,此时形参中存储的值便成为了存储在堆中新new的String字符串地址值
而对于引用数据类型的传参,也是将原变量的值复制一份传递给形参,但是变量中存储的是地址值,所以导致形参和实参指向同一个地址,形参对原地址的改变也就导致了实参的改变
所以Java只有值传递,没有引用传递!!!