Java 到底是按值传递还是按引用传递

来源:互联网 发布:手机为什么仅限2g网络 编辑:程序博客网 时间:2024/04/29 02:44

初学 C++ 时,曾知其方法参数有按值传递和按引用传递之分,例如:

fun(int a , int b) 与 fun(int &a , int &b)。

而在 Java 中,问题就变得简单多了,一切方法都是按值传递。然而,仍有不少资格较老的 Java 程序员,甚至某些书籍均称 Java 是按引用传递,我认为这应当是理解上的差异,而不是认知错误。因此我也发表一下自己的看法,权当加强对这一问题的理解。

在说明问题之前,先看几个例子:

1

pubilc static void main(String[] args){    int value = 5;    System.out.println("before call:value = "+value);    int rs = doubleValue(value);    System.out.println("after call:value = "+value);    System.out.println("fun return:rs = "+rs);}public static int doubleValue(int value){    value = value*2;    return value;}

程序输出为:

before call:value = 5

after call:value = 5

fun return:rs = 10

结论:Java 中基本数据类型为按值调用,即方法不能修改基本数据类型的参数。

2

Class C{public C(int value){this.value = value;}public int value;}Class Test{public static void main(String[] args){C a = new C(5);C b = new C(9);System.out.println("before call: a.value = "+a.value+" , b.value = "+b.value);swap(a , b);System.out.println("after call: a.value = "+a.value+" , b.value = "+b.value);}public static void swap(C a , C b){C temp = a;a = b;b = temp;}}
程序输出为:

before call: a.value = 5 , b.value = 9

after call: a.value = 5 , b.value = 9

结论:Java中引用数据类型亦为按值调用,即方法不能将参数中对象的引用指向新的对象。

3

Class C{public C(int value){this.value = value;}public int value;}Class Test{public static void main(String[] args){C a = new C(5);System.out.println("before call: a.value = "+a.value);doubleValue(a);System.out.println("after call: a.value = "+a.value);}public static void doubleValue(C a){a.value = a.value * 2;}}
程序输出:

before call: a.value = 5

after call: a.value = 10

结论:方法可以修改参数中对象的引用所指向对象的状态。这应当也就是大家为 Java 到底是按值调用还是按引用调用产生争论的原因。


综合以上例子可知,Java 中方法得到的始终只是参数值的一份拷贝,即本质的理解是, Java 中只有按值调用。做个比喻:引用是遥控器,对象是电视机,一台电视机可以被多个遥控器操控,一个遥控器只能操控一台电视机。现有一个遥控器 a ,可以操控一台电视机 A ,当把遥控器 a 作为参数传入一个方法 fun() 中时,方法 fun() 将首先对 a 执行一次拷贝,得到一个新的遥控器 a_copy,在方法中,可以通过 a_copy 来操控电视机 A,修改 A 的各种状态,这也意味着遥控器 a 所能操控的电视机 A 的状态发生了改变;而如果在方法中将遥控器 a_copy 进行调整,使其指向另一台电视机 B,遥控器 a 并不会跟着一起改变指向,这时 a 与 a_copy 之间将不再有任何瓜葛,对 a_copy 的任何操作都不会对 a 产生影响,事实上,一个方法中参数的生命周期局限于方法体之中。

原创粉丝点击