37.值传递
在程序中,我们经常需要将一个变量的值赋给另外一个变量,赋值后,两个变量的值相同,那么,在Java中,它是通过值传递的机制来实现的。
我们首先来看一个例子。这个例子中的参数是引用类型java.util.Date。
import java.util.Date;
public class CallByValueRef {
public static void main(String args[]) {
Date d;
d = new Date();
System.out.println("d is " + d);
System.out.println("");
System.out.println("调用modify()");
System.out.println("从方法 modify()返回的值");
// 按值传递参数给modify()
modify(d);
System.out.println("");
System.out.println("d is " + d);
}
public static void modify(Date d1) {
System.out.println("in modify...");
d1 = null;
System.out.println("d1 is " + d1);
}
}
在这个例子中,声明了一个引用类型的变量d,设置它的初始值为当前时间,然后将它的值打印出来。接着,调用方法modify(),它将一个Date引用类型的变量d1改为null,然后方法将修改后的这个变量d1值打印出来,最后,在main()方法中再将d的值打印出来。
编译并运行这个程序,可以得到如下的输出:
d is Sun Apr 25 12:06:49 CST 2004
调用modify()
从方法 modify()返回的值
in modify...
d1 is null
d is Sun Apr 25 12:06:49 CST 2004
可以看到,在调用modify()后,d的值并没有发生变化。这是因为,传递给方法modify()的只是d的一个副本(copy),因此在方法中modify()中修改的也只是这个副本的值,而它本身的值并没有发生改变。
简单来说,如果传递的变量类型为简单数据类型,那么就是把变量中的值传递过去,相当于这个值的一个副本,进行修改并不会影响到值的原件。
而如果传递的变量类型为引用类型数据,仍旧是把变量中的值的一个副本传递过去。要注意的时候,作为引用变量,在变量中存储的值并不是对象本身数据,而是这个对象的引用,即对象存储地址。所以如果修改这个引用副本值,并不会影响到对象本身。
但是如果你使用这个引用地址,而去对引用的那个地址的对象进行操作,结果是,对象中的数据真的被改变了!
举个例子,对象可以看做是一间房间,数据操作等等都可以看做房间里面的物品。而该对象的引用就是打开这个房间的钥匙。
如果进行变量赋值,即值传递,就相当于重新配制了一把钥匙,这把钥匙如果丢了,损坏了,是不会影响最初的那把钥匙,你还是可以拿第一把钥匙打开房间进入房间的。
但是如果你拿新配制的钥匙进入了房间,并且对房间里的物品做了变动,就相当于通过引用对对象数据做了修改,即使你拿第一把钥匙进入了房间,房间也是被变更的,因为你们进入的是同一个房间。
Java中的参数传递和C++中的参数传递是不一样的。在C++中,传递参数的方式是按照参数类型不同而有所区分的:通过传值的方式来传递简单类型的参数,而通过传引用的方式来传递引用类型的参数。
Java中则做了统一处理,去掉了引用类型的传递,即指针操作。
实际上在Java中,引用类型的值传递,就是拿对象的引用地址做传递的。但是这些操作的复杂性被统一屏蔽掉了。但是其基本的原理要清楚,在以后的调试中可以及时的发现问题的原因,而不至于茫然无措。
上一篇: asp.net HttpWebRequest自动识别网页编码
下一篇: 35.成员变量初始化