读到Hollis大神的文章 为什么说Java中只有值传递 ,颇有收获,记录一下自己的一点理解。
解释这个问题之前,先要了解两个基本概念,形式参数和实际参数。
要想明白什么说Java中只有值传递,要先确定什么是值传递,什么是引用传递。
值传递
实参先复制一份得到一个副本,将这个副本传递给形参。改变形参里的副本并不会影响到实参。
引用传递
传参的时候直接将实参的引用本身传递给形参。当形参发生改变时,实参也会同时改变。
看完上面的定义,很多人的反应是:不对啊!我在形参里改变对象的时候,形参明明同时发生了改变。在实际变成中大家获得的经验肯定也是这样的。下面拿代码来验证一下。
@Test public void test() { // Person是一个自定义的类,里面只有一个属性,name Person lisi = new Person("李四"); changeName(lisi); System.out.println(lisi.getName()); } private void changeName(Person person) { person.setName("张三"); }
怎么肥四?打印出来的不是李四而是张三,形参改变的同时实参也改变了,这不是符合引用传递的描述吗?
不慌!究竟是不是引用传递,代码还得通过下一关的测试。
@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.2节里对象 lisi
会指向新对象,属性name的值肯定是"张三"。结果打印出来的却是"李四",说明对象 lisi
并没有指向新对象,引用传递的说法可以被证明是错误的。
但是回头再来看,为什么2.1节里,对象 lisi
的name属性的值变成了"李四",如果是值传递,就不应该出现这个结果。
真实原因是,实参将自己的拷贝副本传递给了形参。
2.1节图示
2.2节图示
总而言之,Java里的参数传递,传递的是对象的引用的拷贝,这导致了2.1节和2.2节中,两个例子的不同结果。
Hollis大神的文章里提到,这其实是 共享对象传递
。下面引用原文里的话:
传共享对象调用(共享对象传递)
本文由博客群发一文多发等运营工具平台 OpenWrite 发布