• 【Java思考】Java 中的实参与形参之间的传递到底是值传递还是引用传递呢?


    科普:

    • 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进行修改,将不会影响到实际参数。
    • 引用传递(pass by reference)是指在调用函数时将实际参数的地址直接传递到函数中,那么在函数中对参数所进行的修改,将影响到实际参数。
    值传递 引用传递
    根本区别 会创建副本(Copy) 不创建副本,直接引用
    效果 函数中无法改变原始对象 函数中可以改变原始对象

    Java 中的实参与形参之间的传递到底是值传递还是引用传递呢?

    其实之前我和大多数人一样认为:传递的参数如果是“基本数据类型”,那就是“值传递”,如果是“引用类型”(即 对象),那就是“引用传递”。

    但是昨天我突然觉得:好像。。。不一定!
    诶,别急着怼我说:Nemo!你传递过对象没啊,把对象传过去,修改对象的属性值,属性值就是的的确确的修改了啊!

    诶,你说的没错,确实是修改了,但是你也说了是修改对象的属性值,传过去的是对象地址,而你的实际操作并没有对你传入的地址进行修改,只是修改了对象地址下面的属性值。

    如果只是修改对象地址下面的属性值的话,那么值传递和引用传递有差吗?
    值传递:复制对象地址给函数,函数修改对象地址下面的属性值。
    引用传递:引用对象地址给函数,函数修改对象地址下面的属性值。
    这两者有差吗,无论是复制还是引用,传入的对象地址都没有改变,改变的只是对象地址下面的属性值。

    类比:我们可以类比一下,你家的地址是“北京市海淀区清华园1号”
    引用传递:你给我引用你的地址,我过去你的地址那,打开你家的门,偷你家电动车的电瓶。
    值传递:你不给我你的地址,我从网上找到你的地址,复制一份,过去你的地址那,打开你家的门,偷你家电动车的电瓶。
    你瞧瞧,这两者有差吗?无论是怎样拿到你家的地址,你家的电瓶我要定了啊,你家的电瓶都会被修改啊。

    举例代码:

    package temp;
    
    /**
     * @author Nemo
     * @date 2020/6/22
     */
    public class ValueTransfer {
        public static void main(String[] args) {
            Home yourHome = new Home("你的家");
            Nemo nemo = new Nemo();
            nemo.steal(yourHome);
            yourHome.show();
        }
    }
    
    class Home {
        public String name;
        public boolean battery = true;
    
        public boolean isBattery() {
            return battery;
        }
    
        public void setBattery(boolean battery) {
            this.battery = battery;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public Home(String name) {
            this.name = name;
        }
    
        public void show() {
            if (this.isBattery()) {
                System.out.println(name + "的电瓶还在哟~");
            } else {
                System.out.println(name + "的电瓶被偷了!");
            }
        }
    
    }
    
    class Nemo {
        public void steal(Home home) {
            //如果是引用传递的话,那么我把你的家整个都变为了别人的家,那么你的家对象上现在应该存放的是别人的家
            //如果是值传递的话,那么我只是把你的家对象复制了一个新的,这个新的家是别人的家,我偷一个跟你家一模一样的别人家的电瓶,你家的电瓶应该不会变
            home = new Home("别人的家");
            home.battery = false;
            home.show();
        }
    
    }

    在 Nemo 类的 steal 方法中,我们可以看到注释:

    1. 如果是引用传递,那么我把你的家整个都变为了别人的家,那么你的家对象上现在应该存放的是别人的家,并且你家(即 别人家)的电瓶也应该被我偷了。
    2. 如果是值传递,那么我只是把你的家对象参数复制了一个新的,这个新的家我设为了别人的家,我偷一个跟你家一模一样的别人家的电瓶,你家的电瓶应该不会变。

    运行结果:

    别人的家的电瓶被偷了!
    你的家的电瓶还在哟~

    根据运行结果来看,很显然,是第二种情况,也就是值传递,我偷的是一个跟你家一模一样的别人家的电瓶,而你家的电瓶还在。

    结论

    Java 中只有值传递

  • 相关阅读:
    关于DateFormater
    Swift 排查引用循环
    AutoLayout与UIbutton
    UIScrollView 在Autolayout下使用的一些问题
    sourceTree .gitignore文件处理
    Mp4V2与ffmpeg静态库符号冲突问题解决
    iOS 处理HLS视频流
    对于UITableView和UIImageView的DrawRect重写之后的影响
    UILabel的DrawDrect方法
    《iOS面试之道》-勘误2
  • 原文地址:https://www.cnblogs.com/blknemo/p/13178522.html
Copyright © 2020-2023  润新知