面試------String 類和常量池
阿新 • • 發佈:2018-12-24
String 類和常量池
1 String 物件的兩種建立方式:
String str1 = "abcd"; String str2 = new String("abcd"); System.out.println(str1==str2);//false
這兩種不同的建立方法是有差別的,第一種方式是在常量池中拿物件,第二種方式是直接在堆記憶體空間建立一個新的物件。 記住:只要使用new方法,便需要建立新的物件。
2 String 型別的常量池比較特殊。它的主要使用方法有兩種:
- 直接使用雙引號宣告出來的 String 物件會直接儲存在常量池中。
- 如果不是用雙引號宣告的 String 物件,可以使用 String 提供的 intern 方法。String.intern() 是一個 Native 方法,它的作用是:如果執行時常量池中已經包含一個等於此 String 物件內容的字串,則返回常量池中該字串的引用;如果沒有,則在常量池中建立與此 String 內容相同的字串,並返回常量池中建立的字串的引用。
String s1 = new String("計算機"); String s2 = s1.intern(); String s3 = "計算機"; System.out.println(s2);//計算機 System.out.println(s1 == s2);//false,因為一個是堆記憶體中的String物件一個是常量池中的String物件, System.out.println(s3 == s2);//true,因為兩個都是常量池中的String物件
3 String 字串拼接
String str1 = "str"; String str2 = "ing"; String str3 = "str" + "ing";//常量池中的物件 String str4 = str1 + str2; //在堆上建立的新的物件 String str5 = "string";//常量池中的物件 System.out.println(str3 == str4);//false System.out.println(str3 == str5);//true System.out.println(str4 == str5);//false
儘量避免多個字串拼接,因為這樣會重新建立物件。如果需要改變字串的話,可以使用 StringBuilder 或者 StringBuffer。
String s1 = new String("abc");這句話建立了幾個物件?
建立了兩個物件。
驗證:
String s1 = new String("abc");// 堆記憶體的地值值 String s2 = "abc"; System.out.println(s1 == s2);// 輸出false,因為一個是堆記憶體,一個是常量池的記憶體,故兩者是不同的。 System.out.println(s1.equals(s2));// 輸出true
結果:
false
true
解釋:
先有字串"abc"放入常量池,然後 new 了一份字串"abc"放入Java堆(字串常量"abc"在編譯期就已經確定放入常量池,而 Java 堆上的"abc"是在執行期初始化階段才確定),然後 Java 棧的 str1 指向Java堆上的"abc"。
8種基本型別的包裝類和常量池
- Java 基本型別的包裝類的大部分都實現了常量池技術,即Byte,Short,Integer,Long,Character,Boolean;這5種包裝類預設建立了數值[-128,127]的相應型別的快取資料,但是超出此範圍仍然會去建立新的物件。
- 兩種浮點數型別的包裝類 Float,Double 並沒有實現常量池技術。
Integer i1 = 33; Integer i2 = 33; System.out.println(i1 == i2);// 輸出true Integer i11 = 333; Integer i22 = 333; System.out.println(i11 == i22);// 輸出false Double i3 = 1.2; Double i4 = 1.2; System.out.println(i3 == i4);// 輸出false
Integer 快取原始碼:
/** *此方法將始終快取-128到127(包括端點)範圍內的值,並可以快取此範圍之外的其他值。 */ public static Integer valueOf(int i) { if (i >= IntegerCache.low && i <= IntegerCache.high) return IntegerCache.cache[i + (-IntegerCache.low)]; return new Integer(i); }
應用場景:
- Integer i1=40;Java 在編譯的時候會直接將程式碼封裝成Integer i1=Integer.valueOf(40);,從而使用常量池中的物件。
- Integer i1 = new Integer(40);這種情況下會建立新的物件。
Integer i1 = 40; Integer i2 = new Integer(40); System.out.println(i1==i2);//輸出false
Integer比較更豐富的一個例子:
Integer i1 = 40; Integer i2 = 40; Integer i3 = 0; Integer i4 = new Integer(40); Integer i5 = new Integer(40); Integer i6 = new Integer(0); System.out.println("i1=i2 " + (i1 == i2)); System.out.println("i1=i2+i3 " + (i1 == i2 + i3)); System.out.println("i1=i4 " + (i1 == i4)); System.out.println("i4=i5 " + (i4 == i5)); System.out.println("i4=i5+i6 " + (i4 == i5 + i6)); System.out.println("40=i5+i6 " + (40 == i5 + i6));
結果:
i1=i2 true
i1=i2+i3 true
i1=i4 false
i4=i5 false
i4=i5+i6 true
40=i5+i6 true
解釋:
語句i4 == i5 + i6,因為+這個操作符不適用於Integer物件,首先i5和i6進行自動拆箱操作,進行數值相加,即i4 == 40。然後Integer物件無法與數值進行直接比較,所以i4自動拆箱轉為int值40,最終這條語句轉為40 == 40進行數值比較。