2013-02-11 29 views
2

检查这个代码为什么StringBuilder的参照像个通

public class StringbuilderDoubt { 

    public static void main(String args[]){ 
      new StringbuilderDoubt().methodTest(); 
    } 

    public void methodTest(){ 
     String str=new String("Default"); 
     StringBuilder sb=new StringBuilder(); 
     sB1(str,sb); 
     sB2(str,sb); 
     System.out.println(str+".........."+sb); 
    } 
    private void sB1(String str1, StringBuilder sb1){ 
        str1+="str1"; 
        sb1.append("sB1"); 
    } 

    private void sB2(String str2, StringBuilder sb2){ 
     str2+="str2"; 
     sb2.append("sB2"); 
    } 
} 

输出是:Default..........sB1sB2 为什么StringBuilder的工作就像通过引用传递? 在methodTest中,我传递了两个对象字符串和字符串生成器。字符串是按值传递的,但StringBuilder看起来像通过refence和StringBuilder对象从调用方法变得更改。

+1

字符串是不可变的。 – mre 2013-02-11 17:40:37

+0

您正在传递对StringBuilder类_by value_的实例的引用。 Java总是使用按值传递语义。您可以修改传递引用的对象的事实与传递值与传递引用无关。 – GriffeyDog 2013-02-11 20:45:13

回答

2

我在这里看到StringBuilder没有任何问题。

str引用引用的字符串没有任何反应。在你的sB1方法中,你有一个本地参考str1。 “+ =”运算符返回一个新的字符串,但原始字符串不变,不会更改。同样的事情发生在你的sB2方法中。

因此,您的变量str仍然只包含“默认”。

+1

是的。所有的集合和表单值(setter和getter)都发生了变化。 但我感到困惑的是,这违反了价值传递。 对象通过引用传递,但是当我传递String或Integer对象时,它没有被更改。 使用Integer进行检查i1 = new Integer(“20”); – Anoop 2013-02-12 06:36:26

+0

您的字符串“str”正在通过引用传递。但是在你的“sB1”方法中,你的本地“str1”引用是第二个参考。最初它仍然指向字符串“Default”。但是当声明“str1 + =”str1“;”被执行,一个新的字符串被创建,并且引用“str1”现在引用这个新的字符串“Defaultstr1”。但是整个过程中,你的“str”变量仍然指向原始字符串“Default”。 – rgettman 2013-02-12 16:59:24

1

当您将一个StringBuilder实例传递给一个方法时,实例值将按值传递。正如你所看到的,你可以将字符追加到方法内部的StringBuilder实例,而不返回实例值。

如果需要,您也可以返回StringBuilder实例值,但这不是必需的。它没有改变。

这个“通过引用传递”也适用于大多数集合类(List,Map),也适用于您自己的拥有getter和setter的类。

如果您不想要这种行为,您必须对通过的实例进行深层复制。如果你从公共API返回一个Collection类,你会这样做。

+0

是的。所有的集合和表单值(setter和getter)都发生了变化。 – Anoop 2013-02-12 06:13:51

+0

您可以将StringBuilder传递给该方法,并且在该方法返回后,添加到其中的任何字符都将存在。收集也一样。我不知道getter和setter在这里是如何相关的。这可能是其他原因,以避免直接访问公共领域,但您可以将它们分配给传递的对象没有问题,分配的值在方法调用返回后仍然存在。 – h22 2013-02-12 07:48:58

0

因为它通过引用。 参考StringBuilder按值传递。您可以添加字符,它们将在方法返回后位于实例中。同样的方式,你可以传递一个Collection并在invoke方法中添加值 - 这些将被保留。您也可以调用setter或分配公共字段,这些更改也将在返回后保留。

String的引用也是按值传递的,因此在此方法返回后,将新值赋给此引用不起作用。

相关问题