Java中参数传递类型只有值传递 Java中参数传递类型只有值传递

转载:

 http://tjuking.iteye.com/blog/1405532

java核心技术卷I里有一个结论我觉得挺有意思的: java中没有引用传递,只有值传递 
首先看定义: 
值传递,是指方法接收的是调用者提供的值 
引用传递,是指方法接收的是调用者提供的变量地址
 
以前学习C++时把参数传递分为值传递和引用传递,国内的不少java教材愿意把对象的传递理解是引用传递,为什么它们会这么说呢?可以看下面一个例子: 
Java代码    收藏代码
  1. import java.util.Calendar;  
  2. public class ChangeValue {  
  3.     public static void main(String[] args) {  
  4.         Calendar oc = Calendar.getInstance();  
  5.         System.out.println("origin:"+oc.getTime());  
  6.         changeDate(oc);  
  7.         System.out.println("after:"+oc.getTime());        
  8.     }  
  9.       
  10.     static void changeDate(Calendar pd){  
  11.         pd.set(197011);  
  12.     }  
  13. }  

某时刻程序输出: 
origin:Thu Jan 05 21:15:59 CST 2012 
after:Sun Feb 01 21:15:59 CST 1970 

oc对象的值改变了,很多人就认为java对象传递实际上是引用传递。 
过程应该是这样的: 
运行changeDate这个函数时,方法得到的是对象引用的拷贝,oc和pd同时引用同一个对象,所以函数运行结束后,pd已经消失了,但是对引用对象的更改却也影响了oc所引用的同一对象,结合对之前的定义理解,这应该是值传递的过程(传递的是对象引用的拷贝)。 
以下附上另一个例子,两个对象的交换函数(C++中可以轻易实现): 
Java代码    收藏代码
  1. public class Swap {  
  2.     public static void main(String[] args) {  
  3.         ObjectSample o1 = new ObjectSample("hello");  
  4.         ObjectSample o2 = new ObjectSample("你好");  
  5.         System.out.println("before swap o1:"+o1.getTitle()+" o2:"+o2.getTitle());  
  6.         Swap.swapObject(o1, o2);  
  7.         System.out.println("after swap o1:"+o1.getTitle()+" o2:"+o2.getTitle());  
  8.     }  
  9.     static void swapObject(ObjectSample o1, ObjectSample o2){  
  10.         ObjectSample temp = new ObjectSample("temp");  
  11.         temp = o1;  
  12.         o1 = o2;  
  13.         o2 = temp;  
  14.     }  
  15. }  
  16.   
  17. class ObjectSample{  
  18.     private String title;  
  19.       
  20.     ObjectSample(String title){  
  21.         this.title = title;  
  22.     }  
  23.       
  24.     public String getTitle(){  
  25.         return title;  
  26.     }  
  27. }  

输出结果: 
before swap o1:hello o2:你好 
after swap o1:hello o2:你好 

java在交换程序中并没有交换两个对象的值,交换的是两个对象的拷贝,不能实现让对象参数引用一个新对象,究其原因还是因为java是采用了值传递而非引用传递。 

还有不少和以前自己接触的观点不一样的地方,当然需要借鉴的吸收并且经过自己的实践来辨别。
分享到:   
评论
9 楼  kuangc2008 前天    引用
geniuswxk 写道
其实都是叫法不同,基本数据类型直接把数据复制一份,非基本数据类型把它的引用复制一份(其实就是内存地址),相当于多个引用指向同一个对像,调用其中任何一个引用改变这个对象,其他多个引用也随之改变,但当其中一个引用指向别的对象时,原来的引用不发生改变

呵呵,你这几句话就说明白了
8 楼  xyang81 前天    引用
chnhopescg 写道
看了LZ的写的文章,还是有点模糊,以前一直认为上述方式都是引用传递,在传递对象到一个方法里面时,其实传递的是对这个对象的一个引用,相当于是引用地址。

引用类型传递的是内存地址。进入swapObject方法时,会在堆内存中开辟一块内存空间,用于存储方法区中的数据,在该方法空间中新建了3个变量,分别为temp、o1和o2,保存main方法中o1和o2的内存地址值,和main方法中的o1,o2不是同一个变量。但它们指向都是同一个对象,所以改方法区中变量的地址不影响main方法中变量的地址,但是如果在swapObject方法中改变o1和o2对象的title属性时,main方法中的o1和o2对象也会随着改变.
7 楼  greatghoul 2012-02-15    引用
原来如此。
6 楼  Meteor_yun 2012-02-15    引用
大家其实可以分析一下程序在内存中的执行过程就明白了  CODESAGEMENT(代码区) DATASAGEMENT(数据区) STACK(局部变量) HEAP(所有new出来的东西)
5 楼  xfjt297857539 2012-02-15    引用
geniuswxk 写道
其实都是叫法不同,基本数据类型直接把数据复制一份,非基本数据类型把它的引用复制一份(其实就是内存地址),相当于多个引用指向同一个对像,调用其中任何一个引用改变这个对象,其他多个引用也随之改变,但当其中一个引用指向别的对象时,原来的引用不发生改变

不错,学习了...
4 楼  geniuswxk 2012-02-15    引用
其实都是叫法不同,基本数据类型直接把数据复制一份,非基本数据类型把它的引用复制一份(其实就是内存地址),相当于多个引用指向同一个对像,调用其中任何一个引用改变这个对象,其他多个引用也随之改变,但当其中一个引用指向别的对象时,原来的引用不发生改变
3 楼  yuwenchun 2012-02-14    引用
学习了,如果用图解会更清晰明了
2 楼  lyaqys 2012-02-14    引用
chnhopescg 写道
看了LZ的写的文章,还是有点模糊,以前一直认为上述方式都是引用传递,在传递对象到一个方法里面时,其实传递的是对这个对象的一个引用,相当于是引用地址。


引用传递的是传递对象的地址,值传递传递的是值的copy复制了一份。因为Java里面对象本身存放的是地址,所以有C++里面传递“引用”的效果。
1 楼  chnhopescg 2012-02-14    引用
看了LZ的写的文章,还是有点模糊,以前一直认为上述方式都是引用传递,在传递对象到一个方法里面时,其实传递的是对这个对象的一个引用,相当于是引用地址。
java核心技术卷I里有一个结论我觉得挺有意思的: java中没有引用传递,只有值传递 
首先看定义: 
值传递,是指方法接收的是调用者提供的值 
引用传递,是指方法接收的是调用者提供的变量地址
 
以前学习C++时把参数传递分为值传递和引用传递,国内的不少java教材愿意把对象的传递理解是引用传递,为什么它们会这么说呢?可以看下面一个例子: 
Java代码    收藏代码
  1. import java.util.Calendar;  
  2. public class ChangeValue {  
  3.     public static void main(String[] args) {  
  4.         Calendar oc = Calendar.getInstance();  
  5.         System.out.println("origin:"+oc.getTime());  
  6.         changeDate(oc);  
  7.         System.out.println("after:"+oc.getTime());        
  8.     }  
  9.       
  10.     static void changeDate(Calendar pd){  
  11.         pd.set(197011);  
  12.     }  
  13. }  

某时刻程序输出: 
origin:Thu Jan 05 21:15:59 CST 2012 
after:Sun Feb 01 21:15:59 CST 1970 

oc对象的值改变了,很多人就认为java对象传递实际上是引用传递。 
过程应该是这样的: 
运行changeDate这个函数时,方法得到的是对象引用的拷贝,oc和pd同时引用同一个对象,所以函数运行结束后,pd已经消失了,但是对引用对象的更改却也影响了oc所引用的同一对象,结合对之前的定义理解,这应该是值传递的过程(传递的是对象引用的拷贝)。 
以下附上另一个例子,两个对象的交换函数(C++中可以轻易实现): 
Java代码    收藏代码
  1. public class Swap {  
  2.     public static void main(String[] args) {  
  3.         ObjectSample o1 = new ObjectSample("hello");  
  4.         ObjectSample o2 = new ObjectSample("你好");  
  5.         System.out.println("before swap o1:"+o1.getTitle()+" o2:"+o2.getTitle());  
  6.         Swap.swapObject(o1, o2);  
  7.         System.out.println("after swap o1:"+o1.getTitle()+" o2:"+o2.getTitle());  
  8.     }  
  9.     static void swapObject(ObjectSample o1, ObjectSample o2){  
  10.         ObjectSample temp = new ObjectSample("temp");  
  11.         temp = o1;  
  12.         o1 = o2;  
  13.         o2 = temp;  
  14.     }  
  15. }  
  16.   
  17. class ObjectSample{  
  18.     private String title;  
  19.       
  20.     ObjectSample(String title){  
  21.         this.title = title;  
  22.     }  
  23.       
  24.     public String getTitle(){  
  25.         return title;  
  26.     }  
  27. }  

输出结果: 
before swap o1:hello o2:你好 
after swap o1:hello o2:你好 

java在交换程序中并没有交换两个对象的值,交换的是两个对象的拷贝,不能实现让对象参数引用一个新对象,究其原因还是因为java是采用了值传递而非引用传递。 

还有不少和以前自己接触的观点不一样的地方,当然需要借鉴的吸收并且经过自己的实践来辨别。

猜你喜欢

转载自rongdmmap-126-com.iteye.com/blog/1410349
今日推荐