首先,我們來看一段程序
public class StringCompareTest
{
public static void main(String[] args)
{
String s1 = "aaa";
String s2 = "aaa";
System.out.println(s1 == s2);
System.out.println("-------------------");
String s3 = new String("aaa");
String s4 = new String("aaa");
System.out.println(s3 == s4);
System.out.println("-------------------");
String s5 = "aaa";
String s6 = new String("aaa");
System.out.println(s5 == s6);
}
}
你們認爲輸出結果是什麼呢?
javac 編譯的結果是:true , false , false;
我想很多人看到這要糊塗了,創建的字符串都是“aaa",爲什麼比較結果如此迥異呢?嘿嘿,下面是我的一些見解。
這裏要引人字符串池(StringPool)和堆(heap)的概念。
1、對於第一種情況,首先查找StringPool中是否存在“aaa"對象
如果不存在,則在StringPool中創建一個 “aaa"對象, 然後將StringPool中的這個"aaa"對象的地址返回來,賦給引用變量s,這樣s會指向 StringPool中的這個"aaa"字符串對象;
如果存在,則不創建任何對象,直接將StringPool中這個“aaa"對象地址返回來,賦給s引用。因爲s1、s2指向同一個對象”aaa",所以結果爲true.
2、對於第二種情況,首先在StringPool中查找是否有這個對象
如果有,則不在StringPool創建"aaa"對象,直接在堆中(heap)創建"aaa"對象,將"aaa"對象地址返回 賦給s的引用,導致s指向了堆中創建的這個"aaa"對象;
如果沒有,則首先在StringPool中創建一個"aaa"對象,然後再在堆中創建一個"aaa"對象,然後將堆中這個”aaa"對象的地址返回賦給s引用,導致s指向了堆中所創建的這個 “aaa”。因爲s3、s4指向堆中兩個不同的對象,所以結果爲false.
3、 對於第三種情況,s5指向字符串池中的對象,s6指向堆中的對象,所以結果爲false.