欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

37.值传递

程序员文章站 2022-04-29 12:57:56
...

在程序中,我们经常需要将一个变量的值赋给另外一个变量,赋值后,两个变量的值相同,那么,在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中,引用类型的值传递,就是拿对象的引用地址做传递的。但是这些操作的复杂性被统一屏蔽掉了。但是其基本的原理要清楚,在以后的调试中可以及时的发现问题的原因,而不至于茫然无措。