版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_38225558/article/details/82014329
/*
* String : 保存值到常量池
* 常见笔试题:判断指定代码创建了多少个字符串对象
*/
public class Demo{
public static void main(String[] args) {
// TODO Auto-generated method stub
/*
* 1.在堆内存中创建String类型的对象
* 2.在常量池中查找是否有 "Ahello"字面量对象
* 3.没有。则在常量池中新建一个"Ahello"字面量
* 4.把"Ahello"对象的地址值赋值给String对象中的字段s1
*/
String s1 = "A" + "hello";//1个对象 默认变成 Ahello 保存到s1 原因Java对String 的+做了优化:直接转换为一个字符串。 只在常量池中创建一个"Ahello"对象
String s2 = "A";//1个对象 A
String s3 = s2 + "hello";//1个对象 hello 原因:在常量池中找"A" "hello" "Ahello",能找到"A"和"Ahello" 所以只新建一个"hello"
String s4 = new String("A") + new String("hello");//2个对象 A和hello 原因:先在堆中创建2个String对象。然后去常量池中找"A" "hello" "Ahello",能找到。不新建了
}
}
堆栈图分析:
辅助理解:在这里通过java反编译器查看编译的Demo.class字节码文件内容(发现"A"和"hello"自动拼接在一起了):
再来个例子:
public class Demo {
public static void main(String[] args) {
String s = "abc";
/*
* 1.在堆内存中创建String类型的对象
* 2.在常量池中查找是否有 "abc"字面量对象
* 3.没有。则在常量池中新建一个"abc"字面量
* 4.把"abc"对象的地址值赋值给String对象中的字段
*/
String s2 = new String("abc");
String s3 = "A"+"B"+"C";// 1个对象 原因Java对String 的+做了优化:直接转换为一个字符串。 只在常量池中创建一个"ABC"对象
String s4 = "AB"+"C";//0个 原因:先在常量池中找“ABC". 能找到,不新建对象
String s5 = new String("ABC");//1个 原因:先在堆中创建一个String对象。然后去常量池中找”ABC",能找到。不新建了
/*
* 7个 原因:new了3次String:3个对象 字面量:AB ABC(常量池已经有了) ABCDE C DE
*/
String s6 = new String("AB")+new String("C")+new String("DE");
}
}