Java是值传递还是引用传递

根据我个人的理解,我认为: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

以上代码在test()方法中定义了一个基本类型的变量a,然后调用alter()方法试图改变这个变量,最后输出的还是原来的值。

首先我们要清楚,一个方法中的局部变量是存在栈中的,

  ① 如果是基本类型的变量则直接存的是这个变量的值;

  ② 如果是引用类型的变量则存的是值的引用地址,指向堆中具体的对象。

上面的例子中,调用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进行修饰了的,所以引用地址是无法改变的,故无法修改原变量的值。

posted @ 2023-05-17 21:06  RS_mine  阅读(66)  评论(0)    收藏  举报