在日常編碼中查排,String.intern()不算是一個常用的方法铜幽,但是很多同學在面試的時候都會碰到這個問題(鄙視一下這些面試官),這里我們基于內存來詳細分析一下這個方法碟刺。
String.intern()
是一個Native方法锁保,它的作用是:如果字符串常量池中已經包含一個等于此String對象的字符串,則返回代表池中這個字符串的String對象半沽;否則爽柒,將此String對象包含的字符串添加到常量池中,并且返回此String對象的引用者填。先上代碼:
String str1 = new StringBuilder("i'm").append(" T").toString();
System.out.println(str1.intern()==str1);
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);
這段代碼在JDK1.6中運行浩村,會得到兩個false,而在JDK1.7和1.8中運行會得到一個ture和一個false占哟。這個差異的原因是:
- 在JDK1.6中心墅,
intern()
方法會把首次遇到的字符串實例復制到永久代中,返回的也是永久代中這個字符串實例的引用榨乎,而由StringBuilder
創(chuàng)建的字符串實例在Java堆上嗓化,所以必然不是同一個引用。 - 而JDK1.7中已經將運行時常量池從永久代移除谬哀,在Java 堆(Heap)中開辟了一塊區(qū)域存放運行時常量池。因此
intern()
返回的引用和由StringBuilder
創(chuàng)建的那個字符串實例是同一個严肪。 - 對
str2
的比較返回false是因為“java”這個字符串在執(zhí)行StringBuilder.toString()
之前已經出現過史煎,字符串常量池中已經有它的引用了谦屑,不符合“首次出現”的原則,而“i'm T”這個字符串則是首次出現的篇梭,因此返回true氢橙。