六狼论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

新浪微博账号登陆

只需一步,快速开始

搜索
查看: 80|回复: 0

java的值传递与引用传递

[复制链接]

升级  36%

4

主题

4

主题

4

主题

童生

Rank: 1

积分
18
 楼主| 发表于 2013-1-15 01:27:32 | 显示全部楼层 |阅读模式
对于如下代码:
public class Test {        public static void main(String[] args) {        int i = 0 ;        Test test = new Test();        test.valueMethod(i);        System.out.println(i);           }        private void valueMethod(int a){        a = 5;    }}  
运行结果是0,由于参数是基本类型,因此调用时我们传递的是一个值,所以是java中的值传递,它传递的是一个值的副本,因此,在这个局部方法中对传进来的值的修改是不会影响外部变量的,它修改的是副本的值而不是外部成员i的值。
 
而对于如下代码
public class Test {public static void main(String[] args) {DO dos = new DO();dos.setX1(3);Test test = new Test();test.paraMethod(dos);System.out.println(dos.getX1());}private void paraMethod(Object o){DO oo = (DO)o;oo.setX1(5);}}class DO{private int x1 ;public int getX1() {return x1;}public void setX1(int x1) {this.x1 = x1;}} 运行结果却是5,这是因为值传递时候,传递的是值的拷贝,而引用传递时,也是引用的拷贝,它意味着外部变量和局部变量的指针指向同一个对象,当你在局部方法内修改那个对象的值时,实际上是修改的堆中的值,因此外部变量的值也修改了
 
 
再看如下代码:
public class Test {public static void main(String[] args) {DO dos = new DO();dos.setX1(3);Test test = new Test();test.paraMethod(dos);System.out.println(dos.getX1());}private void paraMethod(Object o){DO oo = new DO();oo.setX1(8);o = oo;}}class DO{private int x1 ;public int getX1() {return x1;}public void setX1(int x1) {this.x1 = x1;}} 它的运行结果还是3,有的人就奇怪了,这个和第二个不是类似么,为什么这里没有修改它的值呢
其实知道画堆栈图的人把这里画出来就明白了
 
 
dos是栈中的一个引用,它指向了堆中的x1所代表的值3
1.当你用上面第2段代码时,实际上是拷贝了一个引用传递到局部方法中,我们暂且称这个引用为dos2,dos和dos2都指向了堆中的3,当我们修改dos2的值的时候实际上就是把这个3给改成了5,因此,dos的x1这个值就变成了5。
2.当你用上面第3段代码时,实际拷贝的是一个引用传递到局部方法中,我们也暂且称这个引用为dos2,dos和dos2都指向了堆中的3,现在我在局部方法体中重新定义了一个oo,这个oo又是一个栈中的指针,它指向了堆中的另外一个值为8的堆空间,我把这个引用赋给dos2时,实际上就只是把dos2的指针给变了,而dos继续指向它原来的3,因此最后的结果就为三拉。
 
 
最后总结一下,目前java传递有2种观点
一种是值传递观点,他们认为java只有值传递,没有引用传递,就算参数是一个引用,它也是引用值的副本,所以是值传递
另一种是基本类型为值传递,引用类型就是引用传递。
 
我个人比较支持第一种,不过这个一直都有争议,没有正确答案~~~~。
您需要登录后才可以回帖 登录 | 立即注册 新浪微博账号登陆

本版积分规则

快速回复 返回顶部 返回列表