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

标签 java string scjp

创建了多少个String对象

我正在为 SCJP 学习,我似乎无法解决这个字符串问题。根据我如何看待问题,我似乎看到了几个可能的答案。

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

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 s1 = "spring ";  
String s2 = s1 + "summer ";  
s1.concat("fall ");  
s2.concat(s1);  
s1 += "winter";  
System.out.println(s1 + " " + s2);

问题是

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

和答案

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 会检查字符串池中是否已经存在相同的字符串 - 因此即使您在多个类中有相同的代码,它也会重用它。

您可以使用 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");
    }
}

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

关于java - 文字字符串创建与 String 对象创建,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8316687/

相关文章:

java - 使用正则表达式删除字符串两部分之间的文本

java - Java中的String为什么是不可变的对象,但我在创建一个对象后仍然可以更改它的值?

java - 为什么枚举中的静态和实例初始化 block 的行为与类中的不同

java - 为什么调用构造函数的重写方法而不是他的类中的方法?

java - runnable构造的Thread对象重写了run方法

Java 转换之谜 - Class.cast 与强制转换运算符

java - MySQL 增量列和 DBunit 数据集的问题

java - 如何使用流在没有冗余代码的情况下获取嵌套集合的最小/最大元素?

c - sprintf 反转 int 并存储为 char

python - 字符串操作 - 在参数列表之间串接 '&'