JDK源碼學習(2)-String.intern()方法詳解

1.方法intern()爲java內部方法,如下

 public native String intern();

native方法爲通過jvm進行運行,jdk8中隱藏了該方法的具體處理方法。

2.作用:該方法註釋爲

“如果常量池中存在當前字符串, 就會直接返回當前字符串. 如果常量池中沒有此字符串, 會將此字符串放入常量池中後, 再返回”。


3.測試代碼一

public static void main(String[] args) {
		String s1 = new String("1");
		s1.intern();
		String s2 = "1";
	
		System.out.println(s1 == s2);

		String s3 = new String("1") + new String("1");
		s3.intern();
		String s4 = "11";
		
		System.out.println(s3 == s4);
	}

結果:

jdk6環境下:

false false

jdk8環境下:

false true


原因分析:

1)jdk6的虛擬機結構中常量池主要是在Perm中,即內存模型爲對象存放到java堆區(heap)中,而常量池主要是在java方法區。屬於不同的兩個區域。

  字符串的初始化中,new時會創建一個對象放在java堆中,而通過引號創建則會在常量池中創建常量,兩個區域是隔絕的,因此即使intern之後比較引用的話也不會是相同的。

2)jdk7之後由於之前Perm的大小隻有4M,已經無法滿足項目的發展,因此取消了Perm的限制,而是移動到了堆區,jdk8更是取消了Perm區。

  對於上面代碼,s1創建的時候,生成了一個對象和一個對象的值,因此s1對應的是對象的引用,s2是對應的常量的引用。

 s3初始化的時候對於“11”來說只有一個對象,當調用intern的時候,由於沒有該常量,因此jdk7之後會生成一個指向對象的引用存放到常量中。而當s4初始化之後,s4也直接爲常量中的對象的引用,因此引用值比較之後爲true。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章