作者:Mazin
來源:my.oschina.net/u/3441184/blog/887152
首先我們來看一段代碼:
public class InternTest {
public static void main(String[] args) {
String str1 = new String("hello") + new String("world");
str1.intern();
String str2 = "helloworld";
System.out.println(str1 == str2);//true
System.out.println(str1.intern() == str2);//true
}
}
大家對上面代碼的運行結果一定很疑惑吧,第二個為true可以理解,因為intern的回傳值本來就是該常量在常量池中的地址,但是為什么第一個也是true呢?
其實在 jdk1.7 之前(這里的運行環境是1.8),第一個是false的,
那么是什么導致的呢?答案就是這個intern的實作方式,
在jdk1.7之前的版本,呼叫這個方法的時候,會去常量池中查看是否已經存在這個常量了,如果已經存在,那么直接回傳這個常量在常量池中的地址值,如果不存在,則在常量池中創建一個,并回傳其地址值,
但是在jdk1.7以及之后的版本中,常量池從perm區搬到了heap區,intern檢測到這個常量在常量池中不存在的時候,不會直接在常量池中創建該物件了,而是將堆中的這個物件的參考直接存到常量池中,減少記憶體開銷,
所以呼叫第二行代碼的時候,就是將heap中的地址值存放到常量池中,多以第三行代碼獲取的就是該字串在heap中的地址值,
如果我們將第二行代碼和第三行代碼的順序調換:
public class InternTest {
public static void main(String[] args) {
String str1 = new String("hello") + new String("world");
String str2 = "helloworld";
str1.intern();
System.out.println(str1 == str2);//false
System.out.println(str1.intern() == str2);//true
}
}
通過上面的講解,這個結果相信大家都能明白了吧(這個也是在1.8的環境中),
下面我們再來看看另一段代碼:
public class InternTest {
public static void main(String[] args) {
String str1 = new String("java");
str1.intern();
String str2 = "java";
System.out.println(str1 == str2);//false
System.out.println(str1.intern() == str2);//true
}
}
這個結果其實很好理解,在第一行代碼執行的時候,會在heap中創建一個物件,并且回去常量池中查看該字串是否已經存在,如果不存在,那么久創建一個,所以第二行代碼可以說是沒什么作用的,
近期熱文推薦:
1.Java 15 正式發布, 14 個新特性,重繪你的認知!!
2.終于靠開源專案弄到 IntelliJ IDEA 激活碼了,真香!
3.我用 Java 8 寫了一段邏輯,同事直呼看不懂,你試試看,,
4.吊打 Tomcat ,Undertow 性能很炸!!
5.《Java開發手冊(嵩山版)》最新發布,速速下載!
覺得不錯,別忘了隨手點贊+轉發哦!
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/240354.html
標籤:其他
