

String s=new String(“abc”)时, 虚拟机会先去字符串常量池查找有无 abc 这个字符串对象,如果有就不在字符串常量池创建了,直接在堆中创建一个 abc 字符串对象,然后将堆中这个 abc 的对象地址 返回赋值给变量,如果没有,则先在字符串常量池创建字符串 abc,然后在堆中创建 abc 的字符串对象,然后将堆中这个 abc 的对象地址返回赋值给变量。
java 的栈上存储的是基本数据类型的变量和对象的引用,而对象本身则存储在堆上。 为什么要先在字符串常量池中创建对象,然后再在堆上创建呢?
通常我们会用双引号的方式创建字符串对象,而不是 new 关键字,此时虚拟机会先在字符串常量池中查找有没有"abc"这个字符串对象,如果有,则不创建任何对象,直接将字符串常量池中这个"abc"的对象地址返回,赋给变量 s;如果没有,在字符串常量池中创建"abc"这个对象,然后将其地址返回,赋给变量 s。此时就不用在堆中创建对象了 String s = new String(“abc”); String s1 = new String(“abc”);
这两行代码会创建三个对象,字符串常量池一个、堆上两个。
String s = “abc”; String s1 = “abc”;
这两行代码只会创建一个对象,就是字符串常量池中的那个。