String中的intern方法


一.intern方法的用途

  關於字符串String中的intern方法,是當前的字符對象(通過new出來的對象)可以使用intern方法從常量池中獲取,

如果常量池中不存在該字符串,那么就新建一個這樣的字符串放到常量池中。

  使用常量池的方法一個是通過雙引號定義字符串例如:String S = “1”;還有就是上面的intern方法。

 

二.在JDK1.6和JDK1.7中的區別

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

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

  在jdk1.6中返回false,false,jdk1.7是false,true

  分析:

  在JDK1.6下,StringPool在永久代,通過new關鍵字創建出來的有兩個對象,一個在常量池,一個在堆中。

  

  上圖可以容易的看出兩個s1與s2, s3與s4的地址是不一樣的,所以都返回false

  在JDK1.7下,由於String大量的使用導致永久代經常發生OutOfMemoryError,所以將StringPool搬到heap中

  

  上圖可以看出,為了不浪費heap的內存StringPool中的S3就直接引用了對象S3,所以S3與S4的地址是一致的

 

  第二段代碼

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

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

  分析第二段代碼:

  JDK1.6下,s1與s2,s3與s4的地址是不一致的,一個是堆中的地址,一個是常量池中的地址。

  所以返回false,false。

  JDK1.7下,s1與s2的地址不一致。s3創建好對象,但是s4在stringpool中創建常量,兩個地址也是不一致。

  所以返回false,false。

 

三.intern的使用技巧

  適當的使用可以減少內存的消耗,每次new String都會產生一個新的對象,如果適當的使用String s=new String("1").intern();

能夠適當的獲取常量池的常量。

  由於JDK1.6中String Pool大小限制在1009,底層是hash表加上鏈表組成,如果過度的使用,會導致鏈表過長從而導致速度變慢,所以

不是每個場景都適合使用intern方法(JDK1.7之后可以通過-XX:StringTableSize=99991設定hash表的大小)

 

四.總結        

  注意JDK1.6和JDK1.7中StringPool 的差異,以及大小的不同,合理的運用intern能給程序帶來一定的好處,是系統更加健壯。

 

參考:https://tech.meituan.com/in_depth_understanding_string_intern.html

 

 

 

     

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM