文字字符串创建与字符串对象创建 [英] Literal string creation vs String object creation

查看:72
本文介绍了文字字符串创建与字符串对象创建的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

创建了多少个String对象

How many String object are created

我正在为SCJP学习,我似乎无法解决这个String问题.根据我对问题的看法,我似乎看到了几种可能的答案.

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)

最初我以为5个对象,即

Initially i thought 5 objects, i.e.

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

但是后来我不确定,因为例如编译器会将"A" +"B" 连接为一个对象吗?即创建7个对象?

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);

最后怎么样:

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

在上面的示例中,我认为将仅创建2个对象

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.

这是正确的还是不相关?也就是说,从常量池引用的对象将不同于s2引用引用的对象.

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.

谢谢

另外,请注意,我有兴趣了解创建的对象总数,包括被丢弃的对象,而不仅仅是最终在常量池中结束的对象.

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.

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

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)

代码示例为

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对象中只有两个没有丢失处理

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

谢谢

推荐答案

编译器会将整个"A" +"B" +"C" +"D"连接为一个常量-因此,在您的第一个示例中,最终只有一个字符串创建了 .如果您多次执行相同的代码,则相同的字符串将被重用.将该常量放入类文件中,并且在加载类时,VM会检查字符串池中是否已存在相等的字符串-因此即使您在多个类中具有相同的代码,它也会重用它.

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.

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

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;

但是,在这里:

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

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

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.

例如,这种方法:

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

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

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

这篇关于文字字符串创建与字符串对象创建的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆