如何理解是否已创建新的String对象

时间:2014-01-23 09:58:34

标签: java string oop

我对编译3行程序的答案和结果感到困惑。以下是代码及其操作码:http://pastebin.com/B1xxAjcp如果我不是完全错误,那很明显

String s="abcd";
String s1=new String("efgh");
s.concat("ijkl"); 

这些行对应于这些操作码:

1: istore_1
        2: ldc           #2                  // String abcd
        4: astore_2
        5: new           #3                  // class java/lang/String
        8: dup
        9: ldc           #4                  // String efgh
       11: invokespecial #5                  // Method java/lang/String."<init>
":(Ljava/lang/String;)V
       14: astore_3
       15: aload_2
       16: ldc           #6                  // String ijkl
       18: invokevirtual #7                  // Method java/lang/String.concat:
(Ljava/lang/String;)Ljava/lang/String;

因此,根据我的理解ldc #index意味着不是创建新对象,而是创建对常量文字池的引用,并将其推送到堆栈。

创建了一个新对象,newdup命令发生在ldc #index之前。但是在这个问题How many String object..?中,第二个答案说ldc #index意味着已经创建了String对象,解释如下:

public static void main(java.lang.String[]);
    Code:
       0: ldc           #2                  // String ObjectOneObjectTwo
       2: astore_1
       3: getstatic     #3                  // Field java/lang/System.out:Ljava/io/PrintStream;
       6: aload_1
       7: invokevirtual #4                  // Method java/io/PrintStream.println:(Ljava/lang/String;)V
      10: return
}

As you see, there is only one String object, which contains "ObjectOneObjectTwo".

  • 我无法理解(也没有人帮助我)我在哪里弄错了这个概念?
  • `ldc #index`是否意味着一个对象被创建并与池中的引用链接,但它是否意味着已经创建了一个“新”对象?

3 个答案:

答案 0 :(得分:5)

String s="abcd";

字符串“abcd”中的字符串在字符串池中创建。

String s1=new String("efgh");

字符串“efgh”中的字符串在String池中创建。 创建了新的非实习字符串,将池中的字符串内容复制到其中

s.concat("ijkl"); 

字符串“ijkl”中的字符串是在字符串池中创建的。 创建了新的非实习字符串,将两个实习字符串的内容复制到其中。

这在池中创建了3个String个实例,在String中创建了2个非实习(不在池中)的实例。

编辑添加: lcd字节码操作将池中String的引用(值)推送到堆栈。

答案 1 :(得分:2)

在第一行中,在字符串池中创建一个新字符串“abcd”。字符串对象“s”被赋予对该字符串的引用。在第二行中,在字符串池中创建另一个字符串“efgh”,并创建一个String“s1”类型的新对象,并且它将引用池中创建的新字符串。在第三行中,在字符串池中创建另一个字符串“ijkl”,在concat()操作之后,创建另一个新字符串“abcdijkl”,现在String对象“s”引用这个新创建的字符串。所以,字符串池中有3个对象,堆上有2个。

答案 2 :(得分:1)

我认为这里真实的是:

 String s1=new String("efgh"); //this will create TWO objects : one in the pool and one in the heap.