3

I have some question that I wonder about. I know that string are immutable in Java and therefore a new string object is created rather than changed when for example assigning to a existing string object.

Now to my question. Let's suppose that I have the following piece of code:

String a = "Hello World";
String b = "Hello World";

String res = a.substring(0,4) + b.substring(6,10);

How many string objects will be created by the code at line 3 ? Will each call to substring create a new string object ? Will my code above generate 3 new string objects ?

Thanks in advance

4

2 回答 2

8

Java 中的字符串是不可变的。基本上这意味着,一旦您创建了一个字符串对象,您将无法修改/更改字符串的内容。因此,如果您对“似乎”更改字符串内容的字符串对象执行任何操作,Java 将创建一个新的字符串对象,并对新创建的对象执行操作。

基于此,您上面的代码似乎创建了五个字符串对象 - 两个由声明创建,两个通过调用创建substring,最后一个在连接两个部分后创建。

然而,不变性导致了另一个有趣的结果。JVM 内部维护着一个类似字符串池的东西,用于创建字符串文字。为了节省内存,JVM 将尝试使用该池中的字符串对象。每当您创建一个新的字符串字面量时,JVM 都会循环到池中以查看是否可以使用任何现有的字符串。如果有,JVM 将简单地使用它并返回它。

因此,从技术上讲,在 Java 7 之前,JVM 只会为您的整个代码创建一个字符串对象。即使您的substring调用也不会在池中创建新的字符串对象,它将使用现有的“Hello World”对象,但在这种情况下,它只会使用位置 0 到 3 的字符来首次调用子字符串。从 Java 7 开始, substring 不会共享字符,而是会创建一个新字符。因此,总对象数将为 4 - 最后一个将通过两个子字符串的连接创建。

编辑 要在评论中回答您的问题,请查看Java 语言规范-

在 Java 编程语言中,与 C 不同,char 数组不是 String,String 或 char 数组都不会以 '\u0000'(NUL 字符)结尾。

String 对象是不可变的,也就是说,它的内容永远不会改变,而 char 数组具有可变元素。

String 类中的 toCharArray 方法返回一个字符数组,该数组包含与 String 相同的字符序列。StringBuffer 类在可变字符数组上实现了有用的方法。

所以,不,char 数组在 Java 中不是不可变的,它们是可变的。

于 2013-04-19T15:52:54.083 回答
0

文字a是新创建的并保存在池中。文字b引用a,它不会创建新的。

第 3 行将创建 3 个新字符串,因为子字符串创建一个新字符串,并且每次连接都会创建新字符串。

字符串子字符串(int beginIndex,int endIndex)

返回一个新字符串,它是该字符串的子字符串。子字符串从指定的 beginIndex 开始并延伸到索引 endIndex - 1 处的字符。因此子字符串的长度是 endIndex-beginIndex。

于 2013-04-19T15:48:54.757 回答