Topic: 高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter)

  Print this page

1.高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) Copy to clipboard
Posted by: 小米CS
Posted on: 2004-11-14 23:13

public class Foo {
public static void main(String[] args){
StringBuffer a=new StringBuffer("A");
StringBuffer b=new StringBuffer("B");
operate(a,b);
System.out.println(a+","+b);
}

static void operate(StringBuffer x,StringBuffer y){
x.append (y);
y=x;
}
}


我想的结果是AB,AB
但是运行的结果是AB,B
我自己想是不是跟引用有关
但是一直都想不太明白
望高手指点指点啊

2.Re:高手来看看这个程序,结果我想不明白 [Re: 小米CS] Copy to clipboard
Posted by: dorrenchen
Posted on: 2004-11-14 23:51

because in function call, if parameter is primative, java create new primative values as parameter, if paramter is object, jvm makes a duplicate copy of the reference, which disappears after method completion.

in your main(), you have instance "A", with reference "a", and instance "B" with reference "b". in your operate(), jvm creates new pair of reference x & y for you, you only can use reference x & y to manipulate obj, but x & y can not touch reference a & b. after operate() completes, x & y are gone, and since you didn't change instance "B", you only changed local reference y which is gone after method completion, so result still is "AB, B".

even if change y= new StringBuffer("XYZ"), result is still "AB, B", because you didn't change the original instance, what you did is just assigning a new local instance to local reference "y", and both are gone after method completion.

to print "AB, AB", you have to use the local reference "y" to change the original instance, one way to do is: y.insert(0, "A");

Dorren

3.Re:高手来看看这个程序,结果我想不明白 [Re: 小米CS] Copy to clipboard
Posted by: 小米CS
Posted on: 2004-11-15 09:50

我的理解是这样的,不知道对不对

在main()方法里面:
a引用'A'
b引用'B'
然后作为参数传递给operate()方法

在operate()方法里面:
x引用'A'
y引用'B'

经过x.append(y)以后
x引用'AB'
y引用'B'

再经过y=x以后
x引用'AB'
y引用'AB'

那么x,y的引用是怎么传递到main()里面的a,b去的?
关键是这里想不太明白

4.Re:高手来看看这个程序,结果我想不明白 [Re: 小米CS] Copy to clipboard
Posted by: 小米CS
Posted on: 2004-11-15 10:14

哦,理解了
operate()中,x.append(y),实际上是改变了x引用的内容,由于a跟x引用同一个对象,所以a的引用也会随之改变
而y=x只是改变operate()中y的引用,这个是局部的,不会影响到main()中b的引用
所以结果是AB,B

这样理解应该对了吧

5.Re:高手来看看这个程序,结果我想不明白 [Re: 小米CS] Copy to clipboard
Posted by: JiafanZhou
Posted on: 2004-11-15 21:31

小米CS wrote:
哦,理解了
operate()中,x.append(y),实际上是改变了x引用的内容,由于a跟x引用同一个对象,所以a的引用也会随之改变
而y=x只是改变operate()中y的引用,这个是局部的,不会影响到main()中b的引用
所以结果是AB,B

这样理解应该对了吧

java中参数传递是pass by value而在c#中是可选,一旦是pass by value,传递的值只会影响到方法内,不会影响到方法外。但是primitive type肯定会被改变,因为在内存中的位置不一样。
但是如果一个引用包含多重引用,eg多维数组,多重引用会被影响到。
这里StringBuffer和String类又不同,一个immutable类,一个mutable类,如果你换成String结果又不同。看下一段

public class Foo
{
public static void main(String[] args)
{
String a=new String("A");
String b=new String("B");
operate(a,b);
System.out.println(a+","+b);
}

static void operate(String x,String y){
x+=y;
y=x;
System.out.println(x+" "+y);
}
}

6.Re:高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) [Re: 小米CS] Copy to clipboard
Posted by: dorrenchen
Posted on: 2004-11-15 22:56

you got it, little rice. In parameters passing, java always make a copy of parameter, unless you save them, local primitive/reference will be lost after method completion.

so if you do want x & y values, then save them as class member.


public class ScopeTest {
StringBuffer s1, s2;

void operate(StringBuffer x, StringBuffer y) {
x.append(y);
y = x;

s1 = x; s2 = y;
}

public static void main(String[] args) {
StringBuffer a = new StringBuffer("A");
StringBuffer b = new StringBuffer("B");
ScopeTest t = new ScopeTest();
t.operate(a, b);
System.out.println(t.s1 + "," + t.s2);
}
}

7.Re:高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) [Re: 小米CS] Copy to clipboard
Posted by: xiemoyong2008
Posted on: 2004-11-16 16:45

import java.*;
public class Foo
{
public static void main(String[] args)
{
StringBuffer a=new StringBuffer("A");
StringBuffer b=new StringBuffer("B");
operate(a,b);
}
static void operate(StringBuffer x,StringBuffer y)
{
x.append Thumbs up;
y=x;
System.out.println(x+","+y);
}
}

可以得到你想要的结果。。。。。。。。
是不是,
呵呵!!!!!!!!!!!

8.Re:高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) [Re: 小米CS] Copy to clipboard
Posted by: 234aini
Posted on: 2004-11-16 18:38

public synchronized StringBuffer append(StringBuffer sb) {
  if (sb == null) {
   sb = NULL;
  }

  int len = sb.length();
  int newcount = count + len;
  if (newcount > value.length)
   expandCapacity(newcount);
  sb.getChars(0, len, value, count);
  count = newcount;
  return this;
}
以上是那个方法的实现方式,以为看一下会明白为什么
没想到月看越迷糊了。。。。。

9.Re:高手来看看这个程序,结果我想不明白 [Re: HenryShanley] Copy to clipboard
Posted by: 234aini
Posted on: 2004-11-16 18:42

HenryShanley wrote:
java中参数传递是pass by value而在c#中是可选,一旦是pass by value,传递的值只会影响到方法内,不会影响到方法外。但是primitive type肯定会被改变,因为在内存中的位置不一样。
但是如果一个引用包含多重引用,eg多维数组,多重引用会被影响到。
这里StringBuffer和String类又不同,一个immutable类,一个mutable类,如果你换成String结果又不同。看下一段

public class Foo
{
public static void main(String[] args)
{
String a=new String("A");
String b=new String("B");
operate(a,b);
System.out.println(a+","+b);
}

static void operate(String x,String y){
x+=y;
y=x;
System.out.println(x+" "+y);
}
}


输出结果是:AB,AB
:A,B
这又是为什么呢?

10.Re:高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) [Re: 小米CS] Copy to clipboard
Posted by: chengbd
Posted on: 2004-11-21 20:22

在operate中,x+=y; 将生成的新对象”AB" 给了x;
y=x,y指向和x一样的对象"AB",这样就有了”AB,AB"的输出
再退出operate,a,b这两个变量指向的对象"A","B",没有改变,而且a,b这两个对象也没有改变。这样就有了"A,B"输出。

11.Re:高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) [Re: 小米CS] Copy to clipboard
Posted by: wnfwnfff
Posted on: 2005-01-28 07:36

首先要明白StringBuffer是可以改变的,它不像String 一样不可以改变。
在operate中x.appendThumbs up是改变了x,使它变成了"AB".y=x使得y也指向x即
"AB".(但是一定要明白,这只是在operate中的情况)。而在main中a,b指向的内存中的位置是不变的。由于在operate 函数使得同一个位置中的x变成了"AB",而y并没有变化。所以结果是"AB","B".
呵呵也许说的不太清楚,希望对你有帮助。Smile

12.Re:高手来看看这个程序,结果我想不明白 (pass StringBuffer as parameter) [Re: 小米CS] Copy to clipboard
Posted by: Reeves1016
Posted on: 2005-01-28 13:00

main()方法后形成的关系是a->"A",b->"B"
代入operate()方法后:x->a->"A",y->b->"B"
经过append后:x->a->"AB",y->b->"B"
经过y=x后:y->x->a->"AB",b->"B"
退出operate()后,x,y消失:a->"AB",b->"B"
所以打印结果为a="AB",b="B"


   Powered by Jute Powerful Forum® Version Jute 1.5.6 Ent
Copyright © 2002-2021 Cjsdn Team. All Righits Reserved. 闽ICP备05005120号-1
客服电话 18559299278    客服信箱 714923@qq.com    客服QQ 714923