天天看點

常量池中為什麼會存在"java"這樣的字元串

在知乎看到這樣一個問題:

question1:《深入了解java虛拟機》中有這樣一段代碼

String str1=new StringBuilder("計算機").append("軟體").toString();
System.out.println(str1.intern()==str1);
		
String str2=new StringBuilder("ja").append("va").toString();
System.out.println(str2.intern()==str2);
           

這兩段看似一樣的代碼在JDK1.7中的運作結果卻是true和false

原文是這樣寫的:

在JDK1.7的intern()實作不會再複制執行個體,隻是在常量池中記錄首次出現的執行個體引用。

也就是說"java"這個字元串本來就存在常量池中。為什麼?

question2:既然存在運作時常量池,在使用某些方法的時候,建立了字面量相等的串,有的時候還是會在堆中建立重複的對象而不直接引用常量池,這又是出于什麼樣的考慮?

-------------------------------------------

answer1:原因是這樣的,并沒有java字元串常量池中,有預設字元串常量這樣的機制。而是其實jvm從啟動,到執行main裡面的第一條代碼,要經曆很多的,比如加載rt.jar裡面所有的Class,加載一個class肯定要執行static{}中内容,況且rt.jar中的jdk的類裡面有很多xxx.startWith("java")或者其他用到"java"的代碼,jvm啟動的時候直接按照常量加載進來了丢到internmap裡面了。。。。

answer2:如果是這樣的話,每建立一個對象都需要到常量池中查找一下,會有時間和性能上的開銷,雖然節省了記憶體。存在和開銷間的平衡。

question link:https://www.zhihu.com/question/32672669