Stringtable(串池)常見的面試題詳解
阿新 • • 發佈:2021-01-03
技術標籤:stringtablejava面試java字串面試
一、比較字串是否相等
package cn.itcast.jvm.t1.stringtable;
// StringTable [ "a", "b" ,"ab" ] hashtable 結構,不能擴容
public class Demo1_22 {
// 常量池中的資訊,都會被載入到執行時常量池中, 這時 a b ab 都是常量池中的符號,還沒有變為 java 字串物件
// ldc #2 會把 a 符號變為 "a" 字串物件
// ldc #3 會把 b 符號變為 "b" 字串物件
// ldc #4 會把 ab 符號變為 "ab" 字串物件
public static void main(String[] args) {
String s1 = "a"; // 懶惰的
String s2 = "b";
String s3 = "ab";
String s4 = s1 + s2; // new StringBuilder().append("a").append("b").toString() new String("ab")
String s5 = "a" + "b"; // javac 在編譯期間的優化,結果已經在編譯期確定為ab
System.out.println(s3 == s4); //false(s3在stringtable中,s5在堆中)
System.out.println(s3 == s5); //true(都是在stringtable中)
}
}
ps: s4和s5區別(s4是兩個變數的相加,不能確定最終的結果,所以是隻能在執行期確定,它是最後是通過stringbuffer的string方法重新new出來的,所以在堆中,而s5是兩個字串常量相加,字串常量相加,內容不變,在編譯期就確定了具體的值,如果字串常量池中有,直接從串池中拿,前面s3已經建立了所以直接拿的s3,所有s5和s3相等)
二、常見面試題(比較地址)
(1.8環境)
/**
* 演示字串相關面試題
*/
public class Demo1_21 {
public static void main(String[] args) {
String s1 = "a";
String s2 = "b";
String s3 = "a" + "b"; // 兩個常量的拼接編譯器優化為ab入池
String s4 = s1 + s2; // new String("ab")(兩個變數的拼接,在執行時通過stringbuilder進行拼接,然後通過string返回一個新的字串)
String s5 = "ab";
String s6 = s4.intern();
System.out.println(s3 == s4); // false
System.out.println(s3 == s5); // true
System.out.println(s3 == s6); // true
String x2 = new String("c") + new String("d"); // new String("cd")
x2.intern();
String x1 = "cd";
// 問,如果調換了【最後兩行程式碼】的位置呢,如果是jdk1.6呢
System.out.println(x1 == x2); //true
}
}
三、建立幾個物件的練習
以下幾種情況(均不考慮字串在常量池中已存在的情況):
1、String a="123";
建立了1個物件
jvm在編譯階段會判斷常量池中是否有 "123" 這個常量物件如果有,a直接指向這個常量的引用,如果沒有會在常量池裡建立這個常量物件。
2、String a=new String("123");
建立了2個物件
同情況1,jvm編譯階段判斷常量池中 "123"存在與否,進而來判斷是否建立常量物件,然後執行階段通過new關鍵字在java heap建立String物件。
3、String a="123"+"456";
建立了1個物件
jvm編譯階段過編譯器優化後會把字串常量直接合併成"123456",所有建立物件時最多會在常量池中建立1個物件。
4、String a="123"+new String("456");
建立了4個物件
常量池物件"123" ,"456",new String("456")建立堆物件,還有一個堆物件"123456"。