您能否解释一下为什么以下代码String
和StringBuffer
的处理方式不同,以及值在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
答案 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)就会被删除。
希望这有点帮助...
我想这里有一些有用的输入供您理解
答案 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)。