• Java到底是值传递还是引用传递【通俗易懂】


    我相信很多刚学Java的小伙伴都很难理解Java到底是值传递还是引用传递的问题,但肯定背过这道面试题。确实,Java就是值传递,那什么原理呢?请往下看。

    我们先看一段代码:分析一下这两句打印的结果分别是什么。

    1. public class Test {
    2. public static void main(String[] args) {
    3. double percent = 10;
    4. tripleValue(percent);
    5. System.out.println("percent的值为:" + percent);
    6. }
    7. public static void tripleValue(double x){
    8. x = 3 * x;
    9. System.out.println("x的值为:" + x);
    10. }
    11. }
    1. x的值为:30.0
    2. percent的值为:10.0

    可能有小伙伴会问了,我明明将变量percent传到tripleValue方法中了,并在方法内,将值乘以了3,那x和percent的值都应该是30.0啊?

    嗯,按逻辑讲确实是这样,但Java却不是这么做的,它在你传参的时候,偷偷的将percent变量拷贝了一个“副本”,也就是x,后面再用3 * x的时候,其实乘以的是副本,早就不是你传的percent变量了,等tripleValue方法结束,参数变量x就被干掉了。

    那么肯定又有小伙伴问了,你基本数据类型勉强算你过关,那我传个Java对象总能破你的局了吧,我就不信传一个对象地址,你还没影响?

    嗯,还真是有影响,但你还破不了我的局,请看如下代码,假如我想将员工的工资提高三倍(如果这个员工是我就好了):

    1. public class Test {
    2. public static void main(String[] args) {
    3. Employee e = new Employee(); //创建员工对象
    4. e.setSalary(10.0); //设置e员工的工资为10
    5. tripleSalary(e);
    6. System.out.println("e的工资为:" + e.getSalary());
    7. }
    8. public static void tripleSalary(Employee x){
    9. double addSalary = x.getSalary() * 3; //为员工涨工资
    10. x.setSalary(addSalary);
    11. System.out.println("x的工资为:" + x.getSalary());
    12. }
    13. }
    1. x的工资为:30.0
    2. e的工资为:30.0

    从结果上来看,实现方法改变对象参数的状态是完全可以的。理由也很简单,方法得到的是对象引用的“副本”,原来的对象引用和这个副本都引用同一个对象,就类似于这样:

    在传参的时候,依然搞了一个副本x,但x和e指向的是同一个对象地址,所以x改了,e也改。

    我们再通过一个例子来让你完全理解到底是值传递还是引用传递,下面来编写一个交换两个 Employee 对象的方法:

    1. public static void swap(Employee x, Employee y){
    2. Employee temp = x;
    3. x = y;
    4. y = temp;
    5. }

    如果 Java 对对象采用的是按引用调用,那么这个方法就应该能够实现交换:

    1. Employee a = new Employee();
    2. Employee b = new Employee();
    3. System.out.println("a的地址值为:" + a);
    4. System.out.println("b的地址值为:" + b);
    5. swap(a, b);
    6. System.out.println("交换后a的地址值为:" + a);
    7. System.out.println("交换后b的地址值为:" + b);
    1. a的地址值为:com.example.test.controller.Employee@5caf905d
    2. b的地址值为:com.example.test.controller.Employee@27716f4
    3. 交换后a的地址值为:com.example.test.controller.Employee@5caf905d
    4. 交换后b的地址值为:com.example.test.controller.Employee@27716f4

    从结果上看出,a和b并没有实现交换,其实原因很简单,在传递参数的过程中,还是拷贝了两个副本,a的副本是x,b的副本是y,方法中交换的也是x和y交换,压根没a和b什么事,所以可以得出结论,Java是值传递。

  • 相关阅读:
    基础DML(数据更新)知识点总结及实例讲解
    正则表达式
    国产低功耗Sub-1G全频段收发一体芯片DP4306遥控器、智能抄表、工业控制等应用。
    【Redis 基础】什么是缓存穿透、缓存雪崩和缓存击穿
    01 # 手写 new 的原理
    teb局部路径规划参数调节--差速小车
    Nacos详解
    Jetson Agx_Orin(Ubuntu20.04)设置vnc远程桌面记录
    MyBatis篇---第三篇
    Dubbo的优雅下线原理分析
  • 原文地址:https://blog.csdn.net/qq_38196449/article/details/132708323