瞭解intern(),瞭解字串常量池
阿新 • • 發佈:2018-12-19
intern()是String一個api,平時不常用,但是面試可能會考,掌握intern可避免被面試官問到時大眼瞪小眼的尷尬局面。
當一個String物件呼叫intern()方法時,會首先檢查字串常量池中是否存在equals相等的字串,若存在直接返回常量池中該字串物件,否則建立該字串物件並放入字串常量池。
然而並不是所有建立的字串都會進入常量池。下面直接貼程式碼,每行程式碼都通過備註的形式給出了執行結果和相關解釋。
String a = new String("ab"); //開闢新的堆記憶體,存放字串物件"ab",引用為 a,同時"ab"進入字串常量池 String b = new String("ab"); //開闢新的堆記憶體,存放字串物件"ab",引用為 b,同時"ab"指向字串常量池已有的物件 String c = "ab"; //未開闢新的堆記憶體,直接將引用c指向了字串常量池已有的"ab" String d = "a" + "b"; //通過拼接靜態字串的方式先檢查常量池中是否已有相等的物件,有則直接將引用指向和c相同的物件 String e = "b"; //引用e指向一個新的字串 String f = "a" + e; //和e拼接將產生一個新的物件,即f指向新的記憶體地址 System.out.println(c == d); //true //d通過+拼接的是靜態字串,非引用 System.out.println(f == d); //false //f通過+拼接了一個引用相當於新建立了一個物件。 //通過new 建立的字串物件(a本身,b本身)不會進入字串常量池 System.out.println(a == a.intern()); //false,a沒有進入常量池,但是a.intern()已經進入,二者非同一物件 System.out.println(c == c.intern()); //true,c本來就在字串常量池,所以返回true System.out.println(b.intern() == a); //false,a沒有進入常量池,但是b.intern()已經進入且和a.intern()是同一個物件 System.out.println(b.intern() == c); //true, b.intern()進入了常量池,c和該池子中的物件 //通過+拼接靜態字串得到的字串物件會進入字串常量池 System.out.println(b.intern() == d); //true //非靜態字串通過+拼接不會進入字串常量池 System.out.println(b.intern() == f); //false System.out.println(b.intern() == a.intern()); //true
大體總結3點:
1.new String的方式建立字串物件,構造器引數進入字串常量池,但是物件本身和常量池中的物件是兩個不同的物件。從而導致這種方式產生的字串呼叫intern()方法和本身引用 == 將返回false。
2.靜態宣告的方式定義的字串直接進入字串常量池,如常量池已有該字串,則直接指向已有字串。這種方式產生的字串呼叫intern()方法和本身引用==始終返回true。
3.+拼接靜態字串建立的物件會進入字串常量池,但是+拼接字串引用就不會進入常量池。二者會導致完全不同的結果,前者呼叫intern()和自身==返回true,後者呼叫intern()和自身==返回false。