• Java是值传递还是引用传递


    读到Hollis大神的文章为什么说Java中只有值传递,颇有收获,记录一下自己的一点理解。

    1 值传递和引用传递

    解释这个问题之前,先要了解两个基本概念,形式参数和实际参数。

    • 形式参数:简称形参。函数声明里的参数列表就是形式参数。
    • 实际参数:简称实参。在调用函数的时候传入的就是实际参数。

    实际参数和形式参数

    要想明白什么说Java中只有值传递,要先确定什么是值传递,什么是引用传递。

    • 值传递

      实参先复制一份得到一个副本,将这个副本传递给形参。改变形参里的副本并不会影响到实参。

    • 引用传递

      传参的时候直接将实参的引用本身传递给形参。当形参发生改变时,实参也会同时改变。

    2 为什么说Java里是值传递

    看完上面的定义,很多人的反应是:不对啊!我在形参里改变对象的时候,形参明明同时发生了改变。在实际变成中大家获得的经验肯定也是这样的。下面拿代码来验证一下。

    2.1 改变形参里的属性

    @Test
    public void test() {
        // Person是一个自定义的类,里面只有一个属性,name
        Person lisi = new Person("李四");
        changeName(lisi);
        System.out.println(lisi.getName());
    }
    
    private void changeName(Person person) {
        person.setName("张三");
    }
    

    改变属性

    怎么肥四?打印出来的不是李四而是张三,形参改变的同时实参也改变了,这不是符合引用传递的描述吗?

    不慌!究竟是不是引用传递,代码还得通过下一关的测试。

    2.2 改变形参指向的对象

    @Test
    public void test() {
        // Person是一个自定义的类,里面只有一个属性,name
        Person lisi = new Person("李四");
        changeName(lisi);
        System.out.println(lisi.getName());
    }
    
    private void changeName(Person person) {
        person = new Person("张三");
    }
    

    改变引用

    奇怪!在这个例子里,形参变了,实参却没有变,跟上一个例子的结果不一致。

    2.3 Java里的值传递

    如果是引用传递,2.2节里对象lisi会指向新对象,属性name的值肯定是"张三"。结果打印出来的却是"李四",说明对象lisi并没有指向新对象,引用传递的说法可以被证明是错误的。

    但是回头再来看,为什么2.1节里,对象lisi的name属性的值变成了"李四",如果是值传递,就不应该出现这个结果。

    真实原因是,实参将自己的拷贝副本传递给了形参。

    2.1节图示

    例1

    2.2节图示

    例2

    3 总结

    总而言之,Java里的参数传递,传递的是对象的引用的拷贝,这导致了2.1节和2.2节中,两个例子的不同结果。

    Hollis大神的文章里提到,这其实是共享对象传递。下面引用原文里的话:

    传共享对象调用(共享对象传递)

    • 传共享对象调用中,先获取到实际参数的地址,然后将其复制,并把该地址的拷贝传递给被调函数的形式参数。因为参数的地址都指向同一个对象,所以我们称也之为"传共享对象",所以,如果在被调函数中改变了形式参数的值(这里说的应该是属性值),调用者是可以看到这种变化的。
      本文由博客群发一文多发等运营工具平台 OpenWrite 发布
  • 相关阅读:
    【OpenCV入门指南】第一篇 安装OpenCV
    java.lang.Math中的基本方法
    padding与margin的差别
    怎样做到从程序猿到管理者的跳跃
    秒杀多线程第四篇 一个经典的多线程同步问题
    NETSH WINSOCK RESET这条命令的含义和作用?
    如何在windows系统自带命令查看硬件信息?
    centos6.5 无线网卡配置
    ctagst简单应用,将Vim改造:Ctags,Taglist,Cscope,OmniCppComplete,SuperTab,Winmanager,NERDTree,MiniBufExplorer,vimrc
    lsof 拥有更多的功能
  • 原文地址:https://www.cnblogs.com/FatShallot/p/12840899.html
Copyright © 2020-2023  润新知