Java 编程语言中函数传参只有值传递。
先来了解下什么是值传递,什么是引用传递:
- 值传递:是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
- 引用传递:是指在调用函数时将实际参数的地址直接传递到函数中,这样在函数中如果对参数进行修改,将影响实际参数。
参数类型是基本数据类型,是值传递传递过来的是实参的副本,对形参改变不影响实参。
public class Test {
public static void main(String[] args) {
int n1 = 1;
f(n1);
System.out.println("n1=" + n1);
}
private static void f(int n2) {
n2 = 2;
System.out.println("n2=" + n2);
}
}
/*
运行结果:
n2=2
n1=1
*/
参数类型是引用类型时,也是值传递,而不是引用传递,传过来的是引用参数的副本,副本里存放的是对象的地址。所以在函数里对地址里的值进行改变时才会影响实参。如果是改变了形参指向的地址,例如new操作,那么实参是不受影响的,还是指向原来的对象地址。
public class Test {
public static void main(String[] args) {
User n1 = new User(1);
f(n1);
System.out.println("n1=" + n1.val);
}
private static void f(User n2) {
n2.val = 2; //改变地址里的值
System.out.println("n2=" + n2.val);
}
static class User {
int val;
public User(int val) {
this.val = val;
}
}
}
/*
运行结果:
n2=2
n1=2
*/
public class Test {
public static void main(String[] args) {
User n1 = new User(1);
f(n1);
System.out.println("n1=" + n1.val);
}
private static void f(User n2) {
n2 = new User(2); //指向新地址
System.out.println("n2=" + n2.val);
}
static class User {
int val;
public User(int val) {
this.val = val;
}
}
}
/*
运行结果:
n2=2
n1=1
*/
所以不要认为形参变实参也变就是引用传递,之所以变是因为传的是实参的拷贝,把实参的值也拷贝给了形参,实参的值就是实际对象的地址,所以形参和实参指向了同一个对象,故通过形参改变了该对象的属性值,那么通过实参访问这个属性也是改变后的。
通过第二个例子可以看到改变了形参指向的地址,这时候形参和实参就指向了不同的对象。
再来看看下面的例子体会下 java 函数传参是值传递,而不是引用传递。
public class Test {
public static void main(String[] args) {
String s = "abc";
f(s);
System.out.println("s=" + s);
}
private static void f(String s) {
s = "cba"; //相当于 s = new String("cba");
System.out.println("s=" + s);
}
}
/*
运行结果:
s=cba
s=abc
*/