优秀的编程知识分享平台

网站首页 > 技术文章 正文

「干货」Java是值传递还是引用传递?

nanyue 2024-10-22 13:11:02 技术文章 6 ℃

首先,我们先介绍下什么是值传递,什么是引用传递?

值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。

引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。


面对这个问题时,应该很多人都知道答案是值传递,但为什么可能有些人说不出个所以然,尤其看到下面的示例代码




user对象(使用lombok插件)

@Data
public class User {
    private String name;
}

从上面代码中我们可以看出:

测试1:基本类型是值传递,不会修改外面age的数值;

测试2:对象user是引用传递,因为user的name被改变了;

因此立刻有人说,基本类型都是值传递,对象类型是引用传递,然而真的是这样吗?我们接下来看测试3。

测试3:对象String是值传递,因为外面的值并未改变,似乎与测试2冲突;

其实对于测试2,我们大家理解进入了偏差,我们举个例子:

假设我们有一台电视机(java对象),我们操作电视机都是通过遥控器(对象的引用),现在我们把遥控器copy了一个给你的朋友,此时你朋友针对遥控器做什么改变,都不会影响到你的遥控器,而测试3相当于,你朋友拿到遥控器后,却通过遥控器把电视机设置了别的频道,因此测试方法出错了,其实java中都是值传递,在对象进参数传递的时候时候,值是对象的引用。因此测试4,才是对象的正确测试方法,结论也是正确的

结论:Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用

最后,我们给出一个例子,加深理解

// main函数
public static void main(String[] args) {
  User user2 = new User();
  user2.setName("user2");
  User user3 = new User();
  user3.setName("user3");
  swap(user2,user3);
  System.out.println(user2.getName()); // user2
  System.out.println(user3.getName()); // user3
}
// swap方法
private static void swap(User user, User user1){
    User user2 = user; // user是copy的引用,
    user = user1;// copy的引用重新指向到新的引用不会改变最原始的引用
    user1 = user2;
    System.out.println(user.getName()); // user3
    System.out.println(user1.getName()); // user2
}

根据之前,我们可以很快绘出下图

因此我们如果在swap方法中执行下面代码

user1.setName("123");

那么main函数中,输出的值也会相应改变

System.out.println(user2.getName()); // 123
最近发表
标签列表