使用“+ =”在Java中“更改”字符串时会发生什么?

What is happening when you “alter” a string in Java using “+=”?

我理解Java中的字符串变量是不可变的,因此不能更改。

1
2
3
String myString ="Hello.";
myString +="";
myString +="My name is Kevin";

每次我们"添加"到这个String()中时,实际上我们都在创建一个新的String(),但它的名称与它要连接的字符串的名称相同。这是否意味着内存中有多个变量"mystring"的引用?


每次将String+=进行"修改"/连接时,都会创建一个新的String对象,并用新创建的String替换名为myString的引用。所以不,内存中只有一个引用,但是对象引用每次都指向要更改的对象。字符串是不可变的,因此不能"就地"修改对象。

String is an immutable class in Java. An immutable class is simply a class whose instances cannot be modified. All information in an instance is initialized when the instance is created and the information can not be modified. There are many advantages of immutable classes.

程序员的StAcExchange有一个很好的答案,解释了为什么EDCOX1的0个s在Java中是不可变的,以及更多的细节。

最好的方法是只使用StringBuilder()类:

1
2
3
4
5
String myStringBuilder = new StringBuilder("Hello.");
myStringBuilder.append("");
myStringBuilder.append("My name is Kevin");

System.out.println(myStringBuilder.toString());

然而,EDCOX1〔0〕级联被现代Java编译器自动转换为EDCOX1×8操作。


Java使用字符串池。这是字符串interning概念的一个实现。

In computer science, string interning is a method of storing only one copy of each distinct string value, which must be immutable. Interning strings makes some string processing tasks more time- or space-efficient at the cost of requiring more time when the string is created or interned. The distinct values are stored in a string intern pool.

这意味着对于每个字符串,都会向字符串池添加该特定字符串的副本。保存该字符串的每个变量都指向字符串池中的副本。

字符串Hello.My name is Kevin被添加到字符串池中,因为它们是程序中的文本。

1
String myString ="Hello.";

变量myString开始指向字符串Hello.,该字符串已在字符串池中。

1
myString +="";

字符串Hello.添加到池中(注意末尾的额外空间)。变量myString现在指向了这一点。

1
myString +="My name is Kevin";

字符串Hello. My name is Kevin添加到池中。变量myString现在指向了这一点。池中不再被变量引用的字符串可以进行垃圾收集,因此Hello.(空间在末尾)现在可以进行垃圾收集。


1
String myString ="Hello.";

上面创建了一个新的Object,把"Hello."放到内存中,myString引用了Object

1
myString +="";

在这里您可以看到myString = myString +"";创建了一个""字符串并将其放入内存中,连接将导致创建一个新的String,由myString引用。

注意,与"+"连接的字符串具有O(n2)复杂性,而StringBuilder具有O(n)复杂性。因为每次都为连接结果创建新的String,而StringBuilder则包含一系列字符。因此,String串联比使用StringBuilder效率低,尤其需要建立大量的字符串。


不,您不能访问以前的引用,它留给垃圾收集器收集。换句话说,内存中只有一个引用保存变量的当前值("我的名字是Kevin")。

请注意,如果要经常更改字符串变量,则应使用StringBuilder类。

这里是到StringBuilder类文档的链接你也可以在网上找到很多使用这个课程的例子。

https://docs.oracle.com/javase/8/docs/api/java/lang/stringbuilder.html网站

这里还有你问题的详细答案

何时用Java垃圾回收字符串


这里是定义String引用变量myString的代码。

String is a immutable class, it means there is no modification can be made in object once it created.

这里,"Hello"创建一个字符串对象,并通过mystring引用该对象。

1
2
3
String myString ="Hello.";  //create a Object String contain Hello and refer to myString
myString +="";
myString +="My name is Kevin";

当执行myString+="";时,它通过在字符串中指定"hello"来创建另一个新的字符串对象。

"Hello"创建了一个新的对象,mystring引用它。"Hello"符合垃圾收集条件。

在执行myString +="My name is Kevin";时,它通过在其中具体化"Hello"来创建字符串的另一个新对象。新对象"Hello My Name is Kevin"由字符串类型的mystring引用变量引用。

Now, Your both earlier Objects "Hello" and "Hello/s" is not referenced by any other reference variable, So, It is eligible for garbage Collection.

谢谢