#Java#我要彻底给你讲清楚,Java就是值传递,不接受争辩的那种!( 三 )


     hollis.setGender(\"Male\");
     pt.pass(hollis);
     System.out.println(\"print in mainuser is \" + hollis);
   
public void pass(User user) {
     user.setName(\"hollischuang\");
     System.out.println(\"print in passuser is \" + user);
   

输出结果:
print in passuser is User{name='hollischuang' gender='Male'
print in mainuser is User{name='hollischuang' gender='Male'

可以看到 , 对象类型在被传递到pass方法后 , 在方法内改变了其内容 , 最终调用方main方法中的对象也变了 。
所以 , 很多人说 , 这和引用传递的现象是一样的 , 就是在方法内改变参数的值 , 会影响到调用方 。
但是 , 其实这是走进了一个误区 。
Java中的对象传递很多人通过代码示例的现象说明Java对象是引用传递 , 那么我们就从现象入手 , 先来反驳下这个观点 。
我们前面说过 , 无论是值传递 , 还是引用传递 , 只不过是求值策略的一种 , 那求值策略还有很多 , 比如前面提到的共享对象传递的现象和引用传递也是一样的 。 那凭什么就说Java中的参数传递就一定是引用传递而不是共享对象传递呢?
那么 , Java中的对象传递 , 到底是哪种形式呢?其实 , 还真的就是共享对象传递 。
其实在 《The Java? Tutorials》中 , 是有关于这部分内容的说明的 。 首先是关于基本类型描述如下:

Primitive arguments such as an int or a double are passed into methods by value. This means that any changes to the values of the parameters exist only within the scope of the method. When the method returns the parameters are gone and any changes to them are lost.
即 , 原始参数通过值传递给方法 。 这意味着对参数值的任何更改都只存在于方法的范围内 。 当方法返回时 , 参数将消失 , 对它们的任何更改都将丢失 。
关于对象传递的描述如下:
Reference data type parameters such as objects are also passed into methods by value. This means that when the method returns the passed-in reference still references the same object as before. However the values of the object’s fields can be changed in the method if they have the proper access level.
也就是说 , 引用数据类型参数(如对象)也按值传递给方法 。 这意味着 , 当方法返回时 , 传入的引用仍然引用与以前相同的对象 。 但是 , 如果对象字段具有适当的访问级别 , 则可以在方法中更改这些字段的值 。
这一点官方文档已经很明确的指出了 , Java就是值传递 , 只不过是把对象的引用当做值传递给方法 。 你细品 , 这不就是共享对象传递么?
其实Java中使用的求值策略就是传共享对象调用 , 也就是说 , Java会将对象的地址的拷贝传递给被函数的形式参数 。 只不过\"传共享对象调用\"这个词并不常用 , 所以Java社区的人通常说\"Java是传值调用\" , 这么说也没错 , 因为传共享对象调用其实是传值调用的一个特例 。
值传递和共享对象传递的现象冲突吗?看到这里很多人可能会有一个疑问 , 既然共享对象传递是值传递的一个特例 , 那么为什么他们的现象是完全不同的呢?
难道值传递过程中 , 如果在被调方法中改变了值 , 也有可能会对调用者有影响吗?那到底什么时候会影响什么时候不会影响呢?
其实是不冲突的 , 之所以会有这种疑惑 , 是因为大家对于到底是什么是\"改变值\"有误解 。


推荐阅读