【问题标题】:Java - Strings and the substring methodJava - 字符串和子字符串方法
【发布时间】:2013-04-13 01:47:21
【问题描述】:

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

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

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

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

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

提前致谢

【问题讨论】:

    标签: java string object substring allocation


    【解决方案1】:

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

    第 3 行将创建 3 个新字符串,因为 substring 会创建一个新字符串,而 concatenate 每次都会创建新字符串。

    String substring(int beginIndex,int endIndex)

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

    【讨论】:

    • 想解释一下为什么是 Zim-Zam 所说的 2 而不是 3?
    • @ZiyaoWei 编辑了我的答案。
    • @AchintyaJha 有 2 个 substring 调用 + 1 个连接。
    • 那个编辑并没有改变它应该是 3 的事实,而这个答案说 2。
    • @ZiyaoWei 我说 2 new 带子字符串和 1 带连接。
    【解决方案2】:

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

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

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

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

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

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

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

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

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

    【讨论】:

    • 从技术上讲,只创建了 4 个。代码中的字符串文字使用String.intern() 解析,因此a 和b 在运行时都引用完全相同的字符串。
    • 感谢您的出色回答。
    • “两个是由声明创建的”?
    • 只有一个问题,char数组在java中是可变的吗?
    • Java 7 中String 的最新实现在调用substring() 时不再共享字符数组:它将创建一个新的字符数组来支持子字符串。
    猜你喜欢
    • 2013-04-01
    • 1970-01-01
    • 2016-03-10
    • 1970-01-01
    • 2023-04-08
    • 2017-01-04
    • 1970-01-01
    • 1970-01-01
    • 2010-12-26
    相关资源
    最近更新 更多