文字字符串创建与String对象创建

时间:2011-11-29 19:39:51

标签: java string scjp

创建了多少个String对象

我正在为SCJP学习我似乎无法理解这个String问题。我似乎看到几个可能的答案取决于我如何看待问题。

在以下初始化中,创建了多少个字符串对象?

String s1 = "A" + "B" + "C" + "D";
System.out.println(s1)

最初我想到了5个对象,即

"A"
"B"
"C"
"D"
"ABCD"

但是后来考虑一下我不太确定,因为例如编译器会将"A" + "B"连接成一个对象吗?即创造7个物体?

"A"
"B"
"C"
"D"
"AB"
"ABC"
"ABCD" 

此外,如果代码更改为

,将创建​​多少个对象
String s1 = new String("A" + "B" + "C" + "D");
System.out.println(s1);

最后怎么样:

String s1 = "A";
String s2 = new String("A");

在上面的例子中,我认为只会创建2个对象

object 1 - "A"
object 2 - a String object that refers to the "A" object above.

这是正确的还是不相关?即,从常量池引用的对象将不同于s2引用所引用的对象。

由于

修改

此外,请注意我有兴趣了解创建的对象总数,包括那些最终丢弃的对象,而不仅仅是最终在常量池中的对象。

修改

看看Jon的回答,我可能完全误解了对象的创建方式。我知道String只在常量池中创建一次并且它被重用但是我不确定在构造'final'字符串时经历的过程。以下是我正在阅读的书中的部分,它似乎表明临时对象的创建与此处的答案完全相反。 (或者这本书可能是错的,或者我误解了这本书)

代码示例

String s1 = "spring ";  
String s2 = s1 + "summer ";  
s1.concat("fall ");  
s2.concat(s1);  
s1 += "winter";  
System.out.println(s1 + " " + s2);

问题是

  

输出是什么?对于额外的功劳,有多少String对象以及如何使用   在println语句之前创建了许多参考变量

答案

  

此代码片段的结果为spring water spring summer。那里   是两个参考变量,s1和s2。共有八个   字符串对象创建如下“spring”,“summer”(丢失),“spring   夏天“,”跌倒“(迷失),”春天秋天“(迷失),”春夏“   (失去),“冬天”(迷失),“春天的冬天”(此时“春天”是   丢失)。八个String对象中只有两个不会丢失   过程

由于

3 个答案:

答案 0 :(得分:13)

编译器会将整个“A”+“B”+“C”+“D”连接成一个常量 - 所以在你的第一个例子中,只有一个字符串最终会被创建 。如果多次执行相同的代码,将重用相同的字符串。常量放在类文件中,当加载类时,VM检查字符串池中是否已存在相等的字符串 - 因此即使在多个类中具有相同的代码,它也将重用它。

您可以使用javap验证类中的常量池中只有一个字符串:

javap -v Test

Constant pool:
   #1 = Methodref   #6.#17     //  java/lang/Object."<init>":()V
   #2 = String      #18        //  ABCD
   #3 = Fieldref    #19.#20    //  java/lang/System.out:Ljava/io/PrintStream;

但是,这里:

String s1 = "A";
String s2 = new String("A");

你最终会得到两个独立的字符串对象。每次执行代码时都会重复使用一个(常量)(并在两个语句之间共享),并且每次都会因为构造函数调用而创建一个 new

例如,这个方法:

public static void foo() {
    for (int i = 0; i < 5; i++) {
        String s1 = "A";
        String s2 = new String("A");
    }
}

...将使用六个字符串对象结束 - 一个用于常量,每次调用方法时创建五个 new

答案 1 :(得分:4)

创建了多少个对象?

String s1 = "A" + "B" + "C" + "D";
System.out.println(s1)

一个或没有。这减少到一个可以加载的字符串文字。

String s1 = new String("A" + "B" + "C" + "D");
System.out.println(s1);

这总会创建一个额外的对象。

BTW:字符串通常由两个对象组成,Stringchar[]包装。

答案 2 :(得分:2)

String s1 = "A" + "B" + "C" + "D";

编译器将只创建一个字符串文字“ABCD”并将其放入String池中。将创建一个对象(字符串池中的对象)。


String s1 = new String("A" + "B" + "C" + "D");

此处相同,只是您要从字符串文字中复制它。所以,这里将创建2个对象。一个由new和一个在字符串池中。


String s1 = "A";
String s2 = new String("A");

同样,"A"将是字符串池中的常量。构造函数将复制它。所以这里将创建两个对象。