创建了多少个String对象
我正在为SCJP学习,我似乎无法理解这个String问题.我似乎看到几个可能的答案取决于我如何看待问题.
在以下初始化中,创建了多少个字符串对象?
String s1 = "A" + "B" + "C" + "D";
System.out.println(s1)
Run Code Online (Sandbox Code Playgroud)
最初我认为5个对象,即
"A"
"B"
"C"
"D"
"ABCD"
Run Code Online (Sandbox Code Playgroud)
但是后来考虑一下我不太确定,因为例如编译器会连接"A" + "B"成一个对象吗?即创建7个对象?
"A"
"B"
"C"
"D"
"AB"
"ABC"
"ABCD"
Run Code Online (Sandbox Code Playgroud)
此外,如果代码更改为,将创建多少个对象
String s1 = new String("A" + "B" + "C" + "D");
System.out.println(s1);
Run Code Online (Sandbox Code Playgroud)
最后怎么样:
String s1 = "A";
String s2 = new String("A");
Run Code Online (Sandbox Code Playgroud)
在上面的例子中,我认为只会创建2个对象
object 1 - "A"
object 2 - a String object that refers to the "A" object above.
Run Code Online (Sandbox Code Playgroud)
这是正确的还是不相关?即,从常量池引用的对象将不同于s2引用所引用的对象.
谢谢
此外,请注意我有兴趣知道创建的对象总数,包括那些被丢弃的对象,而不仅仅是那些最终在常量池中结束的对象.
看看Jon的回答,我可能完全误解了对象的创建方式.我知道String只在常量池中创建一次并且它被重用但是我不确定在构造'final'字符串时经历的过程.以下是我正在阅读的书中的部分,它似乎表明临时对象的创建与此处的答案完全相反.(或者这本书错了或我误解了这本书)
代码示例是
String s1 = "spring ";
String s2 = s1 + "summer ";
s1.concat("fall ");
s2.concat(s1);
s1 += "winter";
System.out.println(s1 + " " + s2);
Run Code Online (Sandbox Code Playgroud)
问题是
什么是输出?为了额外的功劳,在println语句之前创建了多少个String对象和多少个引用变量.
答案
这段代码片段的结果是
spring water spring summer.有两个参考变量,s1和s2.共有八个String对象创建如下"spring","summer"(丢失),"spring summer","fall"(丢失),"spring fall"(丢失),"spring spring spring"(丢失) ,"冬天"(迷失),"春天的冬天"(此时"春天"丢失了).在此过程中,八个String对象中只有两个不会丢失
谢谢
Jon*_*eet 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;
Run Code Online (Sandbox Code Playgroud)
但是,这里:
String s1 = "A";
String s2 = new String("A");
Run Code Online (Sandbox Code Playgroud)
你最终会得到两个独立的字符串对象.每次执行代码时都会重用一个(常量)(并在两个语句之间共享),并且每次都会由于构造函数调用而创建一个新的.
例如,这个方法:
public static void foo() {
for (int i = 0; i < 5; i++) {
String s1 = "A";
String s2 = new String("A");
}
}
Run Code Online (Sandbox Code Playgroud)
...将最终使用六个字符串对象 - 一个用于常量,每次调用方法时创建五个新对象.
| 归档时间: |
|
| 查看次数: |
1679 次 |
| 最近记录: |