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

时间:2016-07-09 10:27:33

标签: java string performance memory concatenation

据我所知,Java中的String变量是不可变的,因此无法更改。

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

每次我们向此String()“添加”某些内容时,我们都会有效地创建一个新的String(),但这与其连接的字符串具有相同的名称。这是否意味着内存中有多个引用变量“myString”?

5 个答案:

答案 0 :(得分:6)

每当您修改" /将String+=连接起来时,您就会创建一个新的String对象并替换名为{{的myString 1}}使用新创建的String。所以不,内存中只有一个引用,但引用指向的对象每次都会更改。字符串是不可变的,因此无法修改对象"就位"。

  

String是Java中的不可变类。不可变类只是一个无法修改其实例的类。创建实例时,将初始化实例中的所有信息,并且无法修改信息。不可变类有许多优点。

great answer on the Programmer's StackExchange解释为什么 String在Java中是不可变的,以及有关其运作方式的详细信息。

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

String myStringBuilder = new StringBuilder("Hello.");
myStringBuilder.append(" ");
myStringBuilder.append("My name is Kevin");

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

但是,现代Java编译器会自动将String并置转换为StringBuilder操作。

答案 1 :(得分:2)

不,你无法访问之前的引用,它留给垃圾收集器来收集它。换句话说,在内存中只有一个引用保存变量的当前值(“我的名字是凯文”)

请注意,如果您要更改String变量,则应使用StringBuilder类。

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

https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html

这里也是你问题的详细解答

When will a string be garbage collected in java

答案 2 :(得分:2)

String myString = "Hello.";

以上内容创建了一个新的Object并将"Hello."放入内存中myString引用Object

myString += " ";

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

请注意,与"+"的字符串连接具有O(N2)复杂度,而StringBuilder在复杂性方面具有O(N)。因为每次String包含一系列字符时,都会为连接结果创建新的StringBuilder。因此String连接效率低于使用StringBuilder特别需要构建大量String的效率。

答案 3 :(得分:2)

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

  

在计算机科学中,字符串实习是一种只存储每个不同字符串值的一个副本的方法,该字符串值必须是不可变的。实习字符串使得一些字符串处理任务更加节省时间或空间,代价是在创建或实现字符串时需要更多时间。不同的值存储在字符串实习池中。

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

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

String myString = "Hello.";

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

myString += " ";

字符串Hello.(注意末尾的额外空格)被添加到池中。变量myString现在指向那个。

myString += "My name is Kevin";

字符串Hello. My name is Kevin已添加到池中。变量myString现在指向那个 池中的字符串不再被变量are eligible for garbage collection引用,因此Hello.(末尾的空格)现在可以被垃圾收集。

答案 4 :(得分:1)

此处为您的代码,您可以在其中定义String引用变量myString

  

String 是一个不可变类,它意味着一旦创建对象就不能对其进行修改。

这里"Hello"创建一个String对象并通过myString引用该对象。

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

myString+=" ";被执行时,它会通过其中的concatic“Hello”创建另一个String对象。

"Hello "创建了一个新对象,myString引用它。 "Hello"有资格进行垃圾收集。

再次执行myString += "My name is Kevin";时,它会通过concatinate "Hello "创建另一个新的String对象。 您的新对象"Hello My Name is Kevin"由myString引用String Type变量引用。

  

现在,您之前的对象"Hello""Hello/s"未被任何其他引用变量引用,因此,它有资格进行垃圾收集。

由于