【问题标题】:How many string objects will be created in memory? [duplicate]将在内存中创建多少个字符串对象? [复制]
【发布时间】:2012-06-26 05:00:24
【问题描述】:

下面的代码会创建多少个字符串对象?

String s="";
s+=new String("a");
s+="b";

我在考试中遇到了这个问题。我想知道正确答案。我说的是 2 个对象。
池中包含 "" 、 "b" 的对象和由 new String("a"); 创建的对象;

【问题讨论】:

标签: java string memory object


【解决方案1】:

创建新字符串

之前我们承诺会更多地讨论创建字符串的各种方法之间的细微差别。让我们看几个如何创建 String 的示例,并进一步假设池中不存在其他 String 对象:

String s = "abc"; // creates one String object and one reference variable

在这个简单的例子中,“abc”将进入池中,s 将引用它。

String s = new String("abc"); // creates two objects, and one reference variable

在这种情况下,因为我们使用了new 关键字,Java 将在普通(非池)内存中创建一个新的 String 对象,s 将引用它。此外,字面量“abc”将被放入池中。

来自 SCJP Sun Certified Programmer for Java 6 Study Guide (Exam 310-065).pdf

【讨论】:

    【解决方案2】:

    我会回答另一个更清晰的问题:以下代码 sn-p 中涉及了多少个 String 实例:

    String s="";
    s+=new String("a");
    s+="b";
    

    答案是 6:

    • 空字符串文字:"";
    • 字符串字面量"a";
    • 字符串文字“a”的副本:new String("a");
    • 通过连接s"a" 的副本创建的字符串;
    • 字符串文字"b"
    • 通过连接s"b" 创建的字符串。

    如果您假设之前加载的代码已经创建了三个 String 文字,那么代码 sn-p 会创建 3 个新的 String 实例。

    【讨论】:

    • String s1 = new String("hello"); ,在 JVM 级别创建了多少引用?我知道两个对象:1 在为“hello”加载类时,1 在实际执行命令时。 1 引用是 s1,我怀疑还有第二个引用 s2,它是在类加载时传递给“new String()”构造函数的“hello”字符串的结果。在java中,我们无法在函数或构造函数中传递对象本身,我们只能传递引用。另外,应该有第三个引用 s3,它应该是 new String("hello") 的结果,然后被分配给 s1?
    【解决方案3】:

    在 JITC 情况下实际创建的对象数量是不确定的。 JITC 很可能认识到new String("a") 是一个身份,并且没有引用s 的中间值,因此只创建了StringBuilder。在一般情况下必须模拟一些潜在的副作用(例如,new String() 的参数可能无效),但对于文字,它们不会发生。

    事实上,javac 可以很好地识别结果是“ab”,没有潜在的副作用,并且只生成该值的字符串字面量。 (它在稍微不太复杂的情况下进行字符串组合。)

    【讨论】:

      【解决方案4】:

      字符串 s="";

      不创建任何对象。

      s+=new String("a");

      创建五个对象。 new String、StringBuilder 及其 char[] 以及 String 结果及其 char[]

      s+="b";

      创建四个对象,StringBuilder 及其 char[] 和 String 结果及其 char[]

      所以我一共得到了九个对象,其中三个是字符串对象

      注意:您可以确定“”已经被加载,因为它出现在许多系统类中,包括 ClassLoader 和 Class。

      就本问题而言,字符串“a”和“b”可能被视为新字符串,也可能不被视为新字符串。恕我直言,我不会计算它们,因为它们最多只会创建一次,如果这段代码只运行一次,那么创建多少个字符串就无关紧要了。更有可能有用的是知道每次运行代码时创建了多少对象。

      【讨论】:

      • 问题是关于 String 实例的。不仅仅是对象。
      • "" 真的不创建对象吗?然后我想知道为什么"".equals("") 是可能的。
      • @Pshemo 加载类时字符串文字已经存在,不需要为String s = ""; 创建更多对象它所做的只是从字符串文字池中分配一个引用。在加载类之前,您可以确信 "" 已经在字符串文字池中。
      • 有没有办法分析 java 以显示内存中的对象?
      • @SoboLAN JDK中有2651个对“”的引用,三个在ClassLoader,两个在Class,你可以确定先加载。
      猜你喜欢
      • 1970-01-01
      • 2021-07-04
      • 2015-04-28
      • 2012-05-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-12-29
      • 2012-04-20
      相关资源
      最近更新 更多