在Java中,String類型的數據是通過字符串常量池來存儲的。字符串常量池是Java堆內存中的一個特殊的區域,用來存儲字符串常量對象。
當我們使用字符串字面量創建String對象時,JVM會首先檢查字符串常量池中是否已經存在相同值的字符串對象。如果存在,則返回該對象的引用;如果不存在,則在字符串常量池中創建一個新的字符串對象,并返回該對象的引用。
例如,以下代碼中的str1和str2都是指向字符串常量池中同一個字符串對象的引用:
String str1 = "hello";
String str2 = "hello";
而當使用new關鍵字創建String對象時,JVM會在堆內存中分配一個新的字符串對象,不管字符串常量池中是否存在相同值的字符串對象。因此,以下代碼中的str3和str4指向的是堆內存中的不同的字符串對象:
String str3 = new String("hello");
String str4 = new String("hello");
需要注意的是,字符串常量池中的字符串對象是不可變的,也就是說,一旦創建了一個字符串對象,就不能再修改它的值。如果對一個字符串對象進行修改,實際上是創建了一個新的字符串對象。
為了提高字符串的比較效率,Java還提供了字符串常量池的intern()方法。調用該方法可以將一個字符串對象添加到字符串常量池中,如果字符串常量池中已經存在相同值的字符串對象,則返回該對象的引用;否則,將該對象添加到字符串常量池中,并返回該對象的引用。例如:
String str5 = new String("hello").intern();
String str6 = "hello";
System.out.println(str5 == str6); // 輸出true
通過調用intern()方法,str5的值被添加到了字符串常量池中,所以str5和str6指向的是同一個字符串對象。