JAVA值传递

 
我不记得自己是怎么学到的,但是我相信绝大部分从事java学习Java的人都一直这么以为一个小的技术问题:
在Java中方法参数的传递,对象是传递引用,基本数据类型是传递值。而且一直一来都似乎没有人提出过疑问。
直到最近,我在为公司基本Java开发人员编写考试试卷的时候,我才发现,这错了!在方法中,Java语言中对象传递的是地址,而不是引用,这两个概念是有非常大的差别的,我相信熟悉c++的人都应该知道。
例如下面:假设对象Test有name的属性。
public void call(Test t) {
Test t2 = new Test();
t2.setName("cba');
t.setName("abc");
t = t2 ;
}

public static void main(String[] arg) {
Test obj = new Test();
call (obj) ;
System.out.println("obj"+obj.getName());
}
这个时候,你们可以发现,打印出来的是"abc" ,而不是"cba",原因是这样的,在这次调用中,等于声明了两个变量obj , t,它们指向的是同一个地址,调用call方法,只是将obj指向的地址传递给了t,而obj本身并没有传递过去(也就是没有传递引用),当你重新赋值的时候(也就是将对象引用指向其他存储空间),等于只影响了t,而没有影响obj。
这样的传递方式只能称之为址传递,或者是引用对象传递,而不嫩说是传递引用或者引用传递。
我不知道这究竟属于翻译的错误,还是我们理解的错误。但是这样的问题在c++中是有明显的区分的(通过*与&)




文章时间: 2004-4-06 21:07:10    标题: 引用回复 将这个帖子加入我的Blog

1、首先弄清楚一个问题:Java有没有指针?

对于在C和C++里头曾经给我们带来欢乐同时也有无限痛苦的指针,很多人宁愿它再也不要出现在Java里头。然而事实上,Java是有指针的,Java中每个对象(除基本数据类型以外)的标识符都属于指针的一种。但它们的使用受到了严格的限制和防范,在<Thinking in Java>一书中称它们为句柄。

2、传递句柄
将句柄传递进入一个方法时,指向的仍然是相同的对象。
public class Testit {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
}

private static void swap(Testit swap1, Testit swap2) {
System.out.println("swaping: " + "a= " + swap1 + " name: " + swap1.getName());
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
}

}

输出结果:
before swap: a=com.lib.Testit@16930e2 name: a
swaping: a= com.lib.Testit@16930e2 name: a

3、一个句柄的传递会使调用者的对象发生意外的改变。
public class Testit {
private String name;

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public static void main(String[] args) {
Testit a = new Testit();
a.setName("a");
Testit b = new Testit();
b.setName("b");
System.out.println("before swap: " + "a=" + a + " name: " + a.getName());
swap(a,b);
System.out.println("after swap: " + "a=" + a + " name: " + a.getName());
}

private static void swap(Testit swap1, Testit swap2) {
Testit temp;
temp = swap1;
swap1 = swap2;
swap2 = temp;
swap1.setName("a's name");
swap2.setName("b's name");
}

}

输出结果:
before swap: a=com.lib.Testit@16930e2 name: a
after swap: a=com.lib.Testit@16930e2 name: b's name

我们看到,a依旧是原来那个a,但name却不是原来那个name了!
在swap()方法中,swap1和swap2互相换过来了,这个时候swap2指向的是a,所以在setName()的时候改变的是a的name,而不是b的name。

为什么会这样呢?
liang_chen兄高见:Java里的传值实际上是拷贝引用,而不是拷贝对象。

总结:
1:对于值类型的参数来说,传递的是值的拷贝.
2:对于引用类型的参数来说,传递的是引用本身的拷贝.
所以关键要看你如何理解传值中的这个“值”了。




文章时间: 2004-4-06 22:56:27    标题: 哈哈,好热闹

引用回复 将这个帖子加入我的Blog


没有想到这个问题引起这么多朋友的共鸣,
楼上有位仁兄关于“java传递是引用的拷贝,既不是引用本身,更不是对象。”这句话说得非常好!可惜现今发现的任何一本书都没有说明。
当然这个传递是对象,而不是简单数据类型,简单数据类型还是传递值的拷贝的。
楼上还有一位仁兄拿出了编译原理,这正是问题的所在,传递地址、传递引用、传递结果(也就是值拷贝),这里所说的传递引用和传递地址有什么差别?
楼上的liang_chen的理解非常好,我直到前一段才真正发现(在我身边差不多都不清楚这个问题),三年多的java分析设计开发经验,到今天才理解透这样一个基础的问题,我真是汗颜。:(
所以,其他还在争论不清楚的各位朋友,一定要认真地学习java,不能随便说自己精通的,哈哈,大家多加探讨,继续共同提高。

 

===============================================================================================================================

 

 

public class Test {

 
 public String kk(StringBuffer bf){
  bf.append("99999999999");
  return bf.toString();
 }
 

 /**
  * @param args
  */
 public static void main(String[] args) {
  Test t=new Test();
  StringBuffer bb=new StringBuffer();
  System.out.println(t.kk(bb));
  System.out.println(bb);


 }

}

=============================================================================================================================

比较:如下

=============================================================================================================================

public class Test {
 
 public String kk(StringBuffer bf){
  bf=new StringBuffer("5555555555555");
  return bf.toString();
 }

 /**
  * @param args
  */
 public static void main(String[] args) {
  Test t=new Test();
  StringBuffer bb=new StringBuffer();
  System.out.println(t.kk(bb));
  System.out.println("eeee"+bb);


 }

}

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值