程序设计语言中将参数传递给方法的几种方式:
-
按名调用(call by name) : Algol 语言采用此方式, 已成为历史;
-
按值调用(call by value) : 方法接收到的是调用者提供的 变量值 ;
-
按引用调用(call by reference) : 方法接受到的是调用者低筒的 变量地址 ;
C++ 支持 按值调用 和 按引用调用 :
而 Java 只支持按值调用 , 也就是说方法得到的是所有参数值的一个拷贝, 在方法内对参数值进行修改是不会影响原值的.
然而方法参数有两种类型:
-
基本数据类型: 数字, 布尔值;
-
对象引用.
当方法参数是 对象引用 时, 在方法很容易的调用其 setXXX
方法修改该对象属性值, 在退出方法后该修改仍然有效, 但这仍旧只是按值调用 .
因为参数是 对象引用 , 在该方法内仍旧执行原对象(类似 C++ 的指针), 调用它的 setXXX
方法当然能修改对象属性了. 但也仅限于修改对象属性(状态), 而不能通过new
等方式对原对象进行修改.
如果还有疑问, 就请看看这个例子:
请问在执行 swap()
函数后, 对象 a 和 对象 b 的 name
是否变化?
答案是没有变化. 在 testSwap()
方法中, first
和 second
完成交换并分别指向对方. 但是, 在进入方法时, 它们拿到的是对象引用的拷贝(位置), 类似于:
-
进入
swap()
方法前,a
知道在内存地址为 100 的地方存储了一个MyObject
对象, 'b' 知道在内存地址为 200 的地方存储了另一个MyObject
对象; -
进入
swap()
方法时,a
将它的对象引用复制一份给first
, 也就是说first
知道内存地址为 100 的地方有一个MyObject
对象.second
同理; -
在退出
swap()
方法时,first
与second
交换值, 也就是说first
知道内存地址为 200 的地方有一个MyObject
对象, 它已经跟内存地址为 100 的MyObject
对象没有任何关系了.second
同理; -
在退出
swap()
方法后,first
与second
被销毁,a
仍旧是知道内存地址为 100 的地方有一个MyObject
对象...
其实, 这就是 C/C++ 的指针.
顺便说一句, 通过 C++ 的 按引用调用 可以很方便实现 swap() 函数. 当然, 用指针也是支持滴, 只不过稍微复杂点(这里只给出声明, 有兴趣的同学自己去写实现吧):
综上, java 中的方法参数:
-
不能修改一个基本数据类型的参数(即数值型或布尔型);
-
可以改变一个对象参数的状态;
-
不能让对象参数引用一个新的对象.
学习Java的同学注意了!!!
学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:454297367【长按复制】 我们一起学Java!