String vs StringBuffer返回值

时间:2016-02-03 09:20:33

标签: java string stringbuffer

您能否解释一下为什么以下代码StringStringBuffer的处理方式不同,以及值在StringBuffer中但不在字符串中。

public class MyClass {

    public static void main(String args[]) {
        String str = new String("String Rohan ");
    StringBuffer strBfr = new StringBuffer("String Buffer Rohan "); 

        strUpdate(str);
        strBfrUpdate(strBfr);

        System.out.println(str);
        System.out.println(strBfr);

    }

    private static void strBfrUpdate(StringBuffer strBfr){
        strBfr.append("Kushwaha");
    }

    private static void  strUpdate(String str){
        str += "Kushwaha";
    }
}

输出如下:

  

String Rohan

     

String Buffer Rohan Kushwaha

6 个答案:

答案 0 :(得分:5)

主要方法

String str = new String("String Rohan ");

str是指向Java-JVM的Heap-memory中某个位置的引用(指针)。让我们称这个地方为

STR->一种

private static void  strUpdate(String str){
    //str here is still pointing to A, but technically this parameter
    //is a copy of the reference of the str pointer in the main-method
    //pointing to the same place in the heap
    //str->A
    str += "Kushwaha";
    // this line is short for str = str + "Kushwaha"
    //what happens here that you create a new String-Object in the heap (B)
    //and assigne the new value "String Rohan Kushwaha" to the new pointer
    //if you print it out now (within this method) you get what you would 
    //expect
    System.out.println(str);
    //will result in "String Rohan Kushwaha"
}

但是main方法的str-pointer仍然指向堆中的A位置仍然只有“String Rohan”。因此,一旦你离开方法strUpdate(...)的范围,复制的指针(被重新分配给位置B)就会被删除。

希望这有点帮助...

我想这里有一些有用的输入供您理解

Is Java "pass-by-reference" or "pass-by-value"?

答案 1 :(得分:3)

在strUpdate方法中,您保留对名为str:

的String的引用
private static void  strUpdate(String str){
    str += "Kushwaha";
}

当你写str + =" ...&#34 ;;这意味着:

    str = new String(str + "...");

此时str引用了新的String,但仅限于strUpdate方法。它没有"被收回"主要的。

答案 2 :(得分:2)

String是不可变的(一旦创建后无法更改)object.Every中的每个不可变对象都是线程安全的,这意味着String也是线程安全的。两个线程不能同时使用字符串。

例如,

String  demo= " hello Rohan " ;
// The above object is stored in constant string pool and its value can not be modified.

demo="Bye Rohan" ;     //new "Bye Rohan" string is created in constant pool and referenced by the demo variable            
 // "hello Rohan " string still exists in string constant pool and its value is not overrided but we lost reference to the  "hello Roahn" string  

另一方面,

StringBuffer是可变的意味着可以更改对象的值。通过StringBuffer创建的对象存储在堆中。 StringBuffer与StringBuilder具有相同的方法,但StringBuffer中的每个方法都是同步的,StringBuffer是线程安全的。

为了帮助您更清楚地了解以下链接有一个很好的例子 http://www.javatpoint.com/difference-between-string-and-stringbuffer 这表明HasCode在String中的区别,但对于String缓冲区,HashCode是相同的。 在你的情况下因为String不可变

strUpdate()方法的连接值未添加到主String中。所以它保持不变。
希望这能回答你的问题。

答案 3 :(得分:0)

为了清楚地看到差异,对于identityHashCode,请参阅System#identityHashCode

.baz()

输出(你的不同):

package example;

public class MyClass {

     public static void main(String args[]) {
            String str = new String("String Rohan ");
        StringBuffer strBfr = new StringBuffer("String Buffer Rohan "); 

            System.out.println("--- String ---");
            System.out.println("Before update: " + System.identityHashCode(str));
            strUpdate(str);
            System.out.println("After update: " + System.identityHashCode(str));
            System.out.println("--- StringBuffer ---");
            System.out.println("Before String Buffer update: " + System.identityHashCode(strBfr));
            strBfrUpdate(strBfr);
            System.out.println("After String Buffer update: " + System.identityHashCode(strBfr));

            System.out.println("--- Final output ---");
            System.out.println(str);
            System.out.println(strBfr);

        }

        private static void strBfrUpdate(StringBuffer strBfr){
            System.out.println("StringBuffer parameter: " + System.identityHashCode(strBfr));
            strBfr.append("Kushwaha");
            System.out.println("StringBuffer object modification: " + System.identityHashCode(strBfr));
        }

        private static void  strUpdate(String str){
            System.out.println("Parameter: " + System.identityHashCode(str));
            str += "Kushwaha";
            System.out.println("Modified (a new String, passed String instance remain same and each modification will produce new String instance): " + System.identityHashCode(str));      }
}

另请参阅@Rainer提到的Java "pass-by-reference" or "pass-by-value"

答案 4 :(得分:0)

当我们修改现有字符串时,将在字符串池中创建一个新的字符串实例,字符串引用变量将指向新文字。将删除对旧文字的引用。

在你的情况下,为String创建了两个文字。 一个在main方法中,另一个在strUpdate方法中。 主方法中的引用变量str指向“Rohan”(实际上在输出中打印) 虽然strUpdate方法中的引用变量str指向“Rohan Kushwaha”(如果你在这个方法中打印出来,你会得到“Rohan Kushwaha”)

但是当我们使用StringBuffer作为方法的参数时,我们实际上是在发送对象引用。当我们传递对象作为引用时,修改对于调用方法也是可见的。因此我们看到“Rohan Kushwaha”的字符串 缓冲

答案 5 :(得分:0)

正如Shriram在他的评论中已经说过的:Java中的字符串不可变,一旦创建,就可以进行更改。之前已经多次询问过这个问题(例如here)。