String 在 java 中是一個使用最頻繁的類,也是佔據內存最大的類,合理的優化 String 對象,能夠節省寶貴的內存資源。java
在每次賦值的時候使用,若是常量池中有相同值,就會重複使用該對象,返回對象引用,這樣一開始的對象就能夠被回收掉。數組
上一段代碼優化
String s1 = "abc"; String s2 = new String("abc"); String s3 = s2.intern(); System.out.println("1:" + (s1 == s2)); System.out.println("2:" + (s2 == s3)); System.out.println("3:" + (s1 == s3)); System.out.println("================================"); String s4 = new String("1") + new String("1"); String s5 = "11"; System.out.println("4:" + (s4 == s5)); String s6 = s4.intern(); System.out.println("5:" + (s4 == s5)); System.out.println("6:" + (s5 == s6)); System.out.println("7:" + (s4 == s6));
結果是:指針
1:false 2:false 3:true ================================ 4:false 5:false 6:true 7:false
理解這一塊的核心在於這段代碼運行是分爲2個階段的,1.類加載 2.類執行
code
1.類加載時(注:JDK 1.7 以後,常量池合併在堆中):對象
2.類運行時:在堆內存中開闢一個空間存放該對象,String 類中的 char 數組引用常量池對象,返回堆內存中的地址給變量引用。內存
若是調用 intern() 方法,就會去字符串常量池中查看是否有等於該對象字符串的引用,若是有,就返回返回字符串常量池中的引用
。資源
額外注意 s4 動態生成的字符串
動態生成的字符串直接在堆上建立,字符串常量池沒有,當調用 intern 方法獲取引用時,則會去常量池中判斷是否有相等的引用,若是有返回引用,若是沒有則放入。字符串
intern 方法 不改版自己的指針引用
,從7就能夠看出,s4調用intern 後與 s6 比較,仍不相等。變量
非動態生成的字符串,在類加載時就已經將字符串對象放入常量池中,運行時視對象是常量仍是變量賦值:
intern 方法,若是常量池中沒有匹配的字符串,就將本身放入而後返回,不然返回字符串對象在常量池中的地址。
爲何相等 ?
String a =new String("abc").intern(); String b = new String("abc").intern(); if(a==b) { System.out.print("a==b");}