我有一些我想知道的问题。我知道字符串在Java中是不可变的,因此在分配给现有字符串对象时会创建新的字符串对象而不是更改。
现在回答我的问题。我们假设我有以下代码:
String a = "Hello World";
String b = "Hello World";
String res = a.substring(0,4) + b.substring(6,10);
第3行的代码将创建多少个字符串对象?每次调用substring都会创建一个新的字符串对象吗?上面的代码会生成3个新的字符串对象吗?
提前致谢
答案 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。