Java是值传递还是引用传递
① 当传的是基本类型时,传的是值的拷贝,对拷贝变量的修改不影响原变量;
② 当传的是的引用类型时,传的是引用地址的拷贝,但是拷贝的地址和真实地址指向的都是同一个真实数据,因此可以修改原变量中的值。
首先来解释一下什么是引用传递,什么是值传递。
-
引用传递(pass by reference)是指在调用方法时将实际参数的地址直接传递到方法中,那么在方法中对参数所进行的修改,将影响到实际参数。
-
值传递(pass by value)是指在调用方法时将实际参数拷贝一份传递到方法中,这样在方法中如果对参数进行修改,将不会影响到实际参数。
我们先来看一个简单的例子:
public void test(){
int a = 1;
alter();
System.out.println(a);
}
private void alter(int a){
a = a + 1;
}
// 输出:a的值为1
首先我们要清楚,一个方法中的局部变量是存在栈中的,
① 如果是基本类型的变量则直接存的是这个变量的值;
② 如果是引用类型的变量则存的是值的引用地址,指向堆中具体的对象。
上面的例子中,调用alter()方法传递的a,其实是a变量的拷贝,不是真正的a,在alter()方法中改变的是拷贝,对真正的a是没有影响的。
但是,对于引用类型来讲,还会是这样吗?
pubilc void test(){
User user = new User();
user.setAge(23);
alter(user); // 这里传入的是存放于栈中的User的引用地址
System.out.println("年龄" + user.getAge());
}
private void alter(User user){
user.setAge(24);
}
// 输出:年龄 24
这里却发现该用户的年龄被修改了,原因是当调用alter()方法传入变量时,也是拷贝变量,但是这里的拷贝只是栈中的引用地址,并不会拷贝堆中的数据,虽然变量是拷贝,但是指向的地址是同一个,因此对变量中的数据修改时,还是会影响到原来真实的变量,但是,如果我们修改的是变量在栈中的地址,则不会影响原变量,例如下面这段代码:
public void test(){
User user = new User();
user.setAge(18);
alter(user);
System.out.println("年龄" + user.getAge());
}
private void alter(User user){
user = new User(); // 这里又创建了一个新的User类型的对象,并给形参user赋予了一个新的引用地址
user.setAge(19); // 修改的不再是传进来的那个user了,而是新的user的年龄
}
// 输出:年龄 18
这种是修改变量在栈中的地址,则不会影响原变量。
但是要注意当传入的是不可变的引用类型时,如String,它的底层的数组引用变量是使用final进行修饰了的,所以引用地址是无法改变的,故无法修改原变量的值。

浙公网安备 33010602011771号