一 简单面试题
1 题目
new String("ab")会创建几个对象?
2 代码
/**
* 题目:
* new String("ab")会创建几个对象?看字节码,就知道是两个。
* 第一个对象是:new关键字在堆空间创建的
* 第二个对象是:字符串常量池中的对象"ab"。 字节码指令:ldc
*/
public class StringNewTest {
public static void main(String[] args) {
String str = new String("ab");
}
}
3 分析
转换成字节码
0 new #2 <java/lang/String> // new 关键字在堆空间中创建
3 dup
4 ldc #3 <ab> // 字符串常量池中的对象"ab"。 字节码指令:ldc
6 invokespecial #4 <java/lang/String.<init>>
9 astore_1
10 return
这里面就是两个对象。
第一个对象:new 关键字在堆空间中创建。
第二个对象:字符串常量池中的对象
二 复杂面试题
1 题目
new String("a") + new String("b") 会创建几个对象?
2 代码
/**
* 题目:
* new String("a") + new String("b") 会创建几个对象?
* 对象1: new StringBuilder() ,它是因为字符串拼接操作产生
* 对象2: new String("a")
* 对象3: 常量池中的"a"
* 对象4: new String("b")
* 对象5: 常量池中的"b"
* 深入剖析: StringBuilder 的 toString():
* 对象6 :new String("ab")
* 强调一下,从 StringBuilder 的 toString() 字节码分析来看,调用 toString 方法,不会在常量池中生成 ab。
*
*/
public class StringNewTest {
public static void main(String[] args) {
String str = new String("a") + new String("b");
}
}
3 main 方法字节码分析
0 new #2 <java/lang/StringBuilder> -- 对象1
3 dup
4 invokespecial #3 <java/lang/StringBuilder.<init>>
7 new #4 <java/lang/String> -- 对象2
10 dup
11 ldc #5 <a> -- 对象3
13 invokespecial #6 <java/lang/String.<init>>
16 invokevirtual #7 <java/lang/StringBuilder.append>
19 new #4 <java/lang/String> -- 对象4
22 dup
23 ldc #8 <b> -- 对象5
25 invokespecial #6 <java/lang/String.<init>>
28 invokevirtual #7 <java/lang/StringBuilder.append>
31 invokevirtual #9 <java/lang/StringBuilder.toString> -- 对象6
34 astore_1
35 return
4 StringBuilder 的 toString() 字节码分析
5 结论
一共创建了6个对象。
对象1:new StringBuilder()
对象2:new String("a")
对象3:常量池的 a
对象4:new String("b")
对象5:常量池的 b
对象6:toString中会创建一个 new String("ab")
注意:从 StringBuilder 的 toString() 字节码分析来看,调用 toString 方法,不会在常量池中生成 ab。