一、String s = "abc" 和 String s = new String("abc") 的区别
1、String s = "abc";
创建过程分析:在class文件被JVM装载到内存中,JVM会创建一块String Pool(String缓冲池)。当执行String s = “abc”;时,JVM首先在String Pool中查看是否存在字符串对象“abc”(如何查看呢?用equals()方法判断),如果已存在该对象,则不用创建新的字符串对象“abc”,而直接使用String Pool中已存在的对象“abc”,然后将引用s指向该对象;如果不存在该对象,则先在String Pool中创建一个新的字符串对象“abc”,然后将引用s指向String Pool中创建的新对象。
2.String s = new String("abc");
创建过程分析:当执行String s = new String(“abc”);时,JVM首先在String Pool中查看是否存在字符串对象“abc”,如果不存在该对象,则先在String Pool中创建一个新的字符串对象“abc”,然后执行new String(“abc”)构造方法,在Heap里又创建一个新的字符串对象“abc”(new出来的对象都放在Heap里面),并将引用s指向Heap中创建的新对象;如果已存在该对象,则不用创建新的字符串对象“abc”,而直接使用String Pool中已存在的对象“abc”, 然后执行new String(“abc”)构造方法,在Heap里又创建一个新的字符串对象“abc”,并将引用s指向Heap中创建的新对象。
注意:使用new String(“”)创建的字符串对象时,会在运行期创建新对象存储到Heap中。因此,new String(“abc”)创建字符串对象时,会创建2个对象,编译期在String Pool中创建一个,运行时Heap中创建一个。
二、例程分析
public class TestString{
public static void main(String args[]){
String s1 = new String("abc");//语句1
String s2 = "abc";//语句2
String s3 = new String("abc");//语句3
System.out.println(s1 == s2);//语句4
System.out.println(s1 == s3);//语句5
System.out.println(s2 == s3);//语句6
System.out.println(s1 == s1.intern());//语句7
System.out.println(s2 == s2.intern());//语句8
System.out.println(s1.intern() == s2.intern());//语句9
String hello = "hello";//语句10
String hel = "hel";//语句11
String lo = "lo";//语句12
System.out.println(hello == "hello");//语句13
System.out.println(hello == "hel" + "lo");//语句14
System.out.println(hello == "hel" + lo);//语句15
System.out.println(hello == hel + lo);//语句16
}
}
当执行完语句(1)时,在内存里面创建了两个对象,它们的内容分别都是abc,分别在String Pool(常量池)和Heap(堆)里。
hel + lo 同上,输出false。
因此,当执行完语句(7)(8)(9)后,它们的结果分别是true、true、false、false。
String s1 = "Hello";
s1 = "Java";
String s2 = "Hello";
String s3 = new String("Hello");
System.out.println(s1 == s2);
System.out.println(s2 == s3);