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

发布于 2024-12-19 01:48:36 字数 1588 浏览 0 评论 0原文

我正在为 SCJP 研究创建了多少 String 对象,

我似乎无法解决这个 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 引用引用的对象不同。

谢谢

编辑

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

编辑

看看乔恩的答案,我可能完全误解了对象的创建方式。我知道字符串在常量池中仅创建一次,并且会被重用,但我不确定构造“最终”字符串时所经历的过程。这是我正在阅读的书中的部分,它似乎表明创建临时对象,这与此处的答案完全相反。 (或者也许这本书是错误的,或者我误解了这本书)

代码示例是

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

问题是

输出是什么?对于额外的学分,有多少个 String 对象以及如何 许多引用变量是在 println 语句之前创建的。

以及答案

该代码片段的结果是泉水春夏。那里 是两个参考变量,s1 和 s2。总共有八个 创建的字符串对象如下“spring”、“summer”(丢失)、“spring” 夏天”、“秋天”(丢失)、“春天秋天”(丢失)、“春夏春天” (丢失)、“冬天”(丢失)、“春冬”(此时“春”是 丢失的)。八个 String 对象中只有两个没有丢失 流程

谢谢

How many String object are created

I am studying for the SCJP I cant seem to get my head round this String problem. I seem to see several possible answers depending on how i look at a question.

In the following initialization, how many string objects are created?

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

Initially i thought 5 objects, i.e.

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

But then thinking about it i am not really sure because for example will the compiler concatenate "A" + "B" as one object? i.e creating 7 objects?

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

Also, how many objects will be created if the code was changed to be

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

And finally how about:

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

In the above example i think only 2 objects will be created

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

Is this correct or will they not be related? i.e. the object referred to from the constant pool will be different from the one referred to by the s2 reference.

Thanks

Edit

Also, please note i am interested in knowing the total number of objects created including those that are discarded not just those that eventually end up in the constant pool.

Edit

Looking at Jon's answer i might have totally misunderstood the way the objects are created. I know that a String is created only once in the constant pool and it is reused but im not sure of the process that goes through when the 'final' string is constructed. Here is the section from the book i am reading which seems to suggest that temporary objects get created which is a complete opposite to the answers here. (Or maybe the book is wrong or i misunderstood the book)

The code sample was

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

The question was

What is the output? For extra credit, how many String objects and how
many reference varibles were created prior to the println statement.

And the answer

The result of this code fragment is spring water spring summer. There
are two reference variables, s1 and s2. There were a total of eight
String objects created as follows "spring", "summer" (lost), "spring
summer", "falls"(lost), "spring fall" (lost), "spring summer spring"
(lost), "winter" (lost), "spring winter" (at this point "spring" is
lost). Only two of the eight String objects are not lost in this
process

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

原谅我要高飞 2024-12-26 01:48:36

编译器会将整个“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");

您最终会得到两个单独的字符串对象。每次执行代码时都会重用一个(常量)(并在两个语句之间共享),并且由于每次构造函数调用都会创建一个常量。

例如,此方法:

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

...最终将使用六个字符串对象 - 一个用于常量,以及每次调用该方法时创建的五个对象。

The compiler will concatenate the whole of "A" + "B" + "C" + "D" into a single constant - so in your first example, only a single string ends up created at all. That same string will be reused if you execute the same code multiple times. The constant is put in the class file, and when the class is loaded the VM checks whether an equal string is already in the string pool - so it will reuse it even if you have the same code in multiple classes.

You can verify that only a single string is in the constant pool within the class with 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;

However, here:

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

you do end up with two separate string objects. One (the constant) will be reused every time you execute the code (and is shared between the two statements), and a new one will be created due to the constructor call each time.

So for example, this method:

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

... will end up using six string objects - one for the constant, and five new ones created each time you call the method.

牛↙奶布丁 2024-12-26 01:48:36

创建了多少个对象?

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

一个或一个都没有。这被减少为一个可以已经加载的字符串文字。

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

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

顺便说一句:字符串通常由两个对象组成:String 和它包装的 char[]

How many objects created?

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

One or none. This is reduced to one String literal which could be already loaded.

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

This always creates an extra object.

BTW: A string usually consists of two objects, the String and the char[] it wraps.

再浓的妆也掩不了殇 2024-12-26 01:48:36
String s1 = "A" + "B" + "C" + "D";

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


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

与此相同,只不过您是从字符串文字复制它。因此,这里将创建 2 个对象。一份由 new 负责,一份在字符串池中。


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

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

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

The compiler will create only one string literal "ABCD" and put it in the String pool. One object will be created (the one in the String Pool).


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

Same here, except that you are copying it from the String literal. So, 2 object will be created here. One by the new and one in the String Pool.


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

Same here, "A" will be a constant in the string pool. The constructor will copy it. So here two objects will be created.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文