求救:一个迷惑的问题

dongfengsun 2006-11-22 11:15:47
class example {
private static void swap(StringBuffer s1,StringBuffer s2) {
s1.append("sky");
StringBuffer t;
t = s1;
s1 = s2;
s2 = t;
System.out.println("in :"+s1);
System.out.println("in :"+s2);
}
public static void main(String[ ] args) {
StringBuffer sb1= new StringBuffer();
StringBuffer sb2= new StringBuffer();
sb1.append("ut");
sb2.append("wuhan");
swap(sb1,sb2);
System.out.println(sb1);
System.out.println(sb2);
}
}
打印结果是:
in :wuhan
in :utsky
utsky
wuhan

我是这样想的,因为sb1、sb2是本地变量,那么就是按值传递,传递的是sb1、sb2的一份copy.

于是我就改成这样:
class example {
static StringBuffer sb1= new StringBuffer();
static StringBuffer sb2= new StringBuffer();
private static void swap(StringBuffer s1,StringBuffer s2) {
s1.append("sky");
StringBuffer t;
t = s1;
s1 = s2;
s2 = t;
System.out.println("in :"+s1);
System.out.println("in :"+s2);
}
public static void main(String[ ] args) {
sb1.append("ut");
sb2.append("wuhan");
swap(sb1,sb2);
System.out.println(sb1);
System.out.println(sb2);
}
}
但输出结果仍然一样!
实在搞不明白.

既然是按值传递,传递的就是本地的一份copy,那么为什么里面的append()方法又传回改变后的值了?

求高人解答!
...全文
343 24 打赏 收藏 转发到动态 举报
写回复
用AI写文章
24 条回复
切换为时间正序
请发表友善的回复…
发表回复
lkdtk 2006-12-05
  • 打赏
  • 举报
回复
StringBuffer对象是可以修改的字符串。
它调用append()方法时,不重新分配内存,直接在先前的内存空间里进行修改。
所以会出现swep中的StringBuffer.append改变引用本来的值。导致最后的sb1为utsky
zhangbin_10 2006-12-05
  • 打赏
  • 举报
回复
动了。。
Dishine 2006-11-24
  • 打赏
  • 举报
回复
flyineagle(逆风飞扬)说得非常清楚了

另String类型有点特殊,String的内容是存在一个叫对象池中的。
jicken_woo 2006-11-24
  • 打赏
  • 举报
回复
学习一下。。。
Zero2One 2006-11-23
  • 打赏
  • 举报
回复
如果你用String 就可以看到不同的结果,可以试下。这就是StringBuffer与String 的不同。
Zero2One 2006-11-23
  • 打赏
  • 举报
回复
如果方法的参数是int,char,long等简单类型,则传递的是值得拷贝。
如果方法的参数是对象类型,传递的是引用的拷贝。

private static void swap(StringBuffer s1,StringBuffer s2)
中的参数s1,s2是变量sb1,sb2的引用拷贝,即指向同一个对象。

这是jackxing(Jack) 的解释,我认为是正确的。
至于楼主问的:既然是按值传递,传递的就是本地的一份copy,那么为什么里面的append()方法又传回改变后的值了?
因为你用的是stringbuffer,StringBuffer对象是可以修改的字符串。所以,它调用append()方法时,不用重新分配内存,也就是它直接在先前的内存空间里进行修改。所以值会变。
jackxing 2006-11-23
  • 打赏
  • 举报
回复
如果方法的参数是int,char,long等简单类型,则传递的是值得拷贝。
如果方法的参数是对象类型,传递的是引用的拷贝。

private static void swap(StringBuffer s1,StringBuffer s2)
中的参数s1,s2是变量sb1,sb2的引用拷贝,即指向同一个对象。
dongfengsun 2006-11-23
  • 打赏
  • 举报
回复
快显身吧
dongfengsun 2006-11-23
  • 打赏
  • 举报
回复
为啥还不见高手来解答?
dongfengsun 2006-11-23
  • 打赏
  • 举报
回复
高手呢 继续顶
hyzzf 2006-11-23
  • 打赏
  • 举报
回复
顶一个,楼主,flyineagle(逆风飞扬)说得非常清楚了
Zero2One 2006-11-23
  • 打赏
  • 举报
回复
你误会我的意思了,改成String 以后,输出结果肯定不一样,但是交换还是不会交换,上面说的很清楚了。StringBuffer 改成String后,swap()里的append(),当然要改成+=了,对sb1就不起作用,也就说,sb1的输出将不会有sky。前面一条输出会有的,也就是swap()方法会把这个拼接上去,因为你用+=的话,相当于new了一个字符串
我只能说那么多了,如果还不理解,偶也没办法了.......
dongfengsun 2006-11-23
  • 打赏
  • 举报
回复
继续顶
dongfengsun 2006-11-23
  • 打赏
  • 举报
回复
还是期望高手能够来解答
dongfengsun 2006-11-23
  • 打赏
  • 举报
回复
呵呵 楼上说的还是不对
改成String结果也是一样 只不过有些稍微变化
还是没交换过来.
Zero2One 2006-11-23
  • 打赏
  • 举报
回复
ft!这样来理解吧,就这道题而言:
假设:sb1 ->35(此数字代表内存地址)
sb2 ->36
调用swap()方法后,把sb1的值附给s1,把sb2的值附给s2。
也就是说,s1->35,s2->36。但是注意此时sb1 ->35,sb2 ->36这是不变的。
然后在swap()方法里,s1.append()来拼接一个字符串,注意上StringBuffer,所以在原内存地址里面做修改,而不重新分配内存。所以35内存存储的内容发生变化。
然后s1,s2做交换,只是把s1,s2的指向改变,也就是引用改变,跟内存中存储的内容无关,同时,s1,s2也与sb1,sb2无关。改变后s1->36,s2->35。而sb1 ->35,sb2 ->36。
sacred02 2006-11-23
  • 打赏
  • 举报
回复
还是没人答到点上

首先,先确定一点:传引用是没错的。这也是为什么append()的时候可以更新到地址上的值的原故;
但问题是在交换之后,返回主函数之前,值是交换的了,但返回后为什么没有交换???
期待~~~

继续关注!
dongfengsun 2006-11-22
  • 打赏
  • 举报
回复
我想问的问题是:
为什么swap方法交换不了sb1、sb2的值?
而在方法里面可以交换?
dongfengsun 2006-11-22
  • 打赏
  • 举报
回复
顶啊 高手呢
dongfengsun 2006-11-22
  • 打赏
  • 举报
回复
既然是引用的话 为何对两个引用进行了交换 结果却是交换前的值?
加载更多回复(4)

67,512

社区成员

发帖
与我相关
我的任务
社区描述
J2EE只是Java企业应用。我们需要一个跨J2SE/WEB/EJB的微容器,保护我们的业务核心组件(中间件),以延续它的生命力,而不是依赖J2SE/J2EE版本。
社区管理员
  • Java EE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧