最近在看《java核心技术卷1》,看到4.5章节的时候解决了以前一直有些疑惑的问题。
记录如下:
首先,在程序设计语言中,将参数传递给方法(或函数)的术语有:
按值调用(call by value)表示方法接收的是调用者提供的值。
按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。
书中还提到了Algol的按名称调用。
在java中:
java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。
例如,考虑代码:
double percent = 10;
harry.raiseSalary(persent);
暂且不用管这段代码的具体实现,书中这个章节用了雇员类来解释很多事情,我们现在只要知道这种调用的方式并不能让percent的值进行改变就可以了。
以上是一个简单的例子,说明了java参数传递的方式。下面将从参数为基本数据类型和对象引用两种情况进行分析:
方法参数为基本数据类型:
public static void tripleValue(double x)
{
x = 3 * x;
}
然后调用:
double percent = 10.0;
tripleValue(percent);
调用之后,percent的值还是10.0,并没有什么变化。
下面看一下具体的执行的过程:
1.x被初始化为percent值的一个拷贝,也还是10。
2.x被乘以了3,然后x变成了30,但是percent仍然是10,因为毕竟是对x的操作,并没有改变percent。
3.方法结束之后,x被弃用了,结果percent还是10。
方法参数为对象引用类型:
(Employee为章节中的一个例子的类,这个类中有raiseSalary方法,这个方法的参数是提高工资的百分比。构造函数也不是重点所以参数就用...代替了,不便之处还请谅解)
public static void tripleSalary(Employee x)
{
x.raiseSalary(200);
}
当调用:
harry = new Employee(...);
tripleSalary(harry);
具体的执行过程为:
1.x被初始化为harry值的拷贝,这里是一个对象的引用。
2.raiseSalary方法应用于这个对象的引用,x和harry同时引用的那个Employee对象的薪资提高了200%。
3.方法结束后,参数x不再使用了,但是harry仍然指向那个已经被提高了200%工资的对象。
所以经过以上的例子,有些人可能认为java是按引用调用的,实际上这种理解是不对的。下面举出一个反例:
编写一个交换两个雇员对象的方法:
public static void swap(Employee x, Employee y)
{
Employee temp = x;
x = y;
y = temp;
}
如果是按引用调用的那么应该可以实现对换数据的效果:
Employee a = new Employee("Alice"...);
Employee b = new Employee("Bob"...);
swap(a,b);
但是,并没有改变存储在变量a和b中的对象引用,swap方法其实交换的是方法中的xy的引用,也就是a和b的拷贝。对于方法外的ab是没有影响的。
这个过程说明了java对对象采用的也不是按引用调用,也是按值调用的。
总结java中方法参数的使用情况:
1.一个方法不能修改一个基本数据类型的参数。
2.一个方法可以改变一个对象参数的状态。(比如修改这个对象中的某个属性值)
3.一个方法不能让对象参数引用一个新的对象。(这句话我的理解是不管你在函数中怎么折腾传进来的那个对象的引用,函数结束了之后对外面都没什么效果,当然了,如果修改了引用对象内的属性,那就属于情况2的情况了。这句话是对交换的例子的总结)
总之
java是按照传值调用的,而不是引用,希望以上的例子和解释能给新手或者对这部分不太清楚的同学们些帮助,如果有不恰当的地方,还请指教。
谢了!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。