字符串對象是一種特殊的對象.String類是一個不可變的類..也就說,String對象一旦建立就不容許修改 String類有一個對應的String池,也就是 String pool.每個內容相同的字符串對象都對應於一個pool裏的對象面試
public class Demo { public static void main(String[] args) { String s = new String("abc"); String s1 = "abc"; String s2 = new String("abc"); System.out.println(s == s1); System.out.println(s == s2); System.out.println(s1 == s2); } }
請問 前面三條語句分別建立了幾個對象,分別是什麼.後面的輸出分別是什麼api
(1)String s = new String("abc"); 這句,建立了兩個對象..其內容都是"abc".注意,s不是對象,只是引用.只有new生成的纔是對象.函數
建立的流程是,首先括號裏的"abc"先到String pool裏看有沒"abc"這個對象,沒有則在pool裏建立這個對象..因此這裏就在pool建立了一個"abc"對象.而後 經過new語句又建立了一個"abc"對象..而這個對象是放在內存的堆裏. .這裏的s指向堆裏的對象..net
(2) String s1 = "abc"; 這條語句,s1固然仍是引用.沒啥可說的.後面的"abc".其實就是上面括號裏的"abc".執行的是相同的操做.即 在pool裏查找有沒"abc"這個對象.沒有則建立一個...很顯然,第一條語句在pool裏已經建立了一個"abc".因此這條語句沒有建立對象,s1指向的是pool中的"abc"code
(3)String s2 = new String("abc"); 這條語句,其實和第一條是同樣的,可是,由於第一條已經在pool中建立了"abc"這個對象,因此,這條語句建立了一個對象.s2指向的是堆裏的"abc".注意,雖然內容都是"abc",s與s2表示的是不一樣的對象對象
(4)接下來就很好說了.下面的三個==判斷.(注意,==永遠是判斷內存地址是否相等) s與s1,一個指向堆裏的對象,一個指向pool裏的.很明顯是不一樣的對象.s與s2.上面說了,雖然都是指向堆裏的對象,內容也是"abc",可是也不是相同的對象.s1與s2.一個指向pool,一個指向堆.也不是相同的對象.因此三個都返回false.blog
public class Demo { public static void main(String[] args) { String s = new String("abc"); String s1 = "abc"; String s2 = new String("abc"); System.out.println(s == s1.intern()); System.out.println(s == s2.intern()); System.out.println(s1 == s2.intern()); } }
求最後輸出是什麼內存
解答.最後的答案是 false false true文檔
intern()方法.按照jdk的幫助文檔來講,是返回字符串對象的規範化表示形式。通俗一點說,就是返回對應這個字符串內容的那個pool裏的對象.這樣說也許還看不太明白,那能夠拿具體例子來講字符串
s1.intern().他的執行流程是,在pool裏去查找s1對應的內容(也就是"abc").若是找到,則返回pool裏的對象.若是沒有(老實說,我沒想到有哪一種狀況是沒有的),則在Pool建立這個對象,並返回...
這樣就很容易理解了.s1.intern返回的是pool裏的"abc"對象.與s這個堆裏的對象確定不一樣,返回false.同理,s與s2.intern()也確定不一樣,返回false.第三個,s1與s2.intern().其中s2.intern()返回的是pool中的"abc"對象,而s1也是指向pool中的"abc"對象.因此返回的是true:
public class Demo { public static void main(String[] args) { String s = new String("abc"); String s1 = "abc"; String s2 = new String("abc"); System.out.println(s == s1.intern()); System.out.println(s == s2.intern()); System.out.println(s1 == s2.intern()); } }
求輸出的結果
解答 true false
首先,上面已經說明了,hello hel lo這三個都是指向pool中的對象..
如今咱們考慮"hel" + "lo" 按照內容來講,兩個相加也就是"hello".這個時候,這個會返回pool中的"hello"對象.因此,hello == "hel" + "lo" 返回的是true .
而"hel" + lo 雖然內容也是"hello",可是它將在堆裏面生成一個"hello"對象,並返回這個對象...因此這裏的結果是false
轉載地址:Java技術——你真的瞭解String類的intern()方法嗎
public class Demo { public static void main(String[] args) { String a = "a1"; String b = "a" + 1; System.out.println(a == b); } }
public class Demo { public static void main(String[] args) { String a = "ab"; String bb = "b"; String b = "a" + bb; System.out.println(a == b); } }
public class Demo { public static void main(String[] args) { String a = "ab"; final String bb = "b"; String b = "a" + bb; System.out.println(a == b); } }
public static void main(String[] args) { String a = "ab"; final String bb = getBB(); String b = "a" + bb; System.out.println(a == b); } private static String getBB() { return "b"; }
private static String a = "ab"; public static void main(String[] args) { String s1 = "a"; String s2 = "b"; String s = s1 + s2; System.out.println(s == a); System.out.println(s.intern() == a); }
private static String a = new String("ab"); public static void main(String[] args) { String s1 = "a"; String s2 = "b"; String s = s1 + s2; System.out.println(s == a); System.out.println(s.intern() == a); System.out.println(s.intern() == a.intern()); }
1)true 要說明一點:當兩個字符串字面值鏈接時(相加),獲得的新字符串依然是字符串字面值,保存在常量池中。
2)false 當字符串字面值與String類型變量鏈接時,獲得的新字符串再也不保存在常量池中,而是在堆中新建一個String對象來存放。很明顯常量池中要求的存放的是常量,有String類型變量固然不能存在常量池中了。
3)true 注意此題與上一題的區別,此處是字符串字面值與String類型常量鏈接,獲得的新字符串依然保存在常量池中。
4)false 此題中第條語句:final String bb = getBB();其實與final String bb = new String(「b」);是同樣的。也就是說return 「b」會在堆中建立一個String對象保存」b」,雖然bb被定義成了final。可見並不是定義爲final的就保存在常量池中,很明顯此處bb常量引用的String對象保存在堆中,由於getBB()獲得的String已經保存在堆中了,final的String引用並不會改變String已經保存在堆中這個事實。
5)false,true 可能不少人對intern()這個函數不瞭解。JDK API文檔中對intern()方法的描述是: 返回字符串對象的規範化表示形式。 一個初始爲空的字符串池,它由類 String 私有地維護。 當調用 intern 方法時,若是池已經包含一個等於此 String 對象的字符串(用 equals(Object) 方法肯定),則返回池中的字符串。不然,將此 String 對象添加到池中,並返回此 String 對象的引用。 它遵循如下規則:對於任意兩個字符串 s 和 t,當且僅當 s.equals(t) 爲 true 時,s.intern() == t.intern() 才爲 true。 全部字面值字符串和字符串賦值常量表達式都使用 intern 方法進行操做。 上面字符串池即爲字符串常量池。明白該題結果的緣由了吧。
6)false,false,true 第五題看明白後,第六題就沒什麼好講的了
轉載地址:jdk在線文檔 String.intern()方法
轉載地址:Java技術——你真的瞭解String類的intern()方法嗎
轉載地址:JAVA --String類筆試面試題