Java - 字符串和子字符串方法

时间:2013-04-19 15:45:20

标签: java string object substring allocation

我有一些我想知道的问题。我知道字符串在Java中是不可变的,因此在分配给现有字符串对象时会创建新的字符串对象而不是更改。

现在回答我的问题。我们假设我有以下代码:

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

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

第3行的代码将创建多少个字符串对象?每次调用substring都会创建一个新的字符串对象吗?上面的代码会生成3个新的字符串对象吗?

提前致谢

2 个答案:

答案 0 :(得分:5)

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

基于此,上面的代码似乎创建了五个字符串对象 - 两个是由声明创建的,两个是通过调用substring创建的,最后一个是在连接两个部分后创建的。 / p> 然而,不变性导致了另一个有趣的后果。 JVM在内部维护类似字符串池的内容,用于创建字符串文字。为了节省内存,JVM将尝试使用此池中的字符串对象。无论何时创建新的字符串文字,JVM都会循环到池中以查看是否可以使用任何现有字符串。如果有,JVM将只使用它并返回它。

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

修改 要在评论中回答您的问题,请查看Java Language Specification -

  

在Java编程语言中,与C不同,char数组不是   字符串,并且字符串和char数组都不会被终止   '\ u0000'(NUL角色)。

     

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

     

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

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

答案 1 :(得分:0)

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

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

String substring(int beginIndex,int endIndex)

  

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