String類的零碎知識點

String類的零碎知識點

1、關於==和equals

前者是引用一致判斷,對內存中引用對象的比較,如果兩個對象指向了同一個內存空間(或叫內存地址,封裝一下叫引用對象),則返回true;

後者是自定義的比較,如果不重寫equals默認和==一樣,但是後者可以通過改寫hashcode和equals方法來實現自定義比較;

相比==,equals更注重內容一致性判斷;

對於==返回ture的,equals一定返回true;反之則不一定。

2、對於String類的賦值:new String(“abc”)&& “abc”

String str1 = new String(“abc”);   
String str2 = “abc”;
String str3 = new String(“abc”);
String str4 = “abc”;
String str5 = “ab”+”c”;
  • 對於str1,虛擬機直接在堆區創建一個對象,然後讓str1指向該對象;
  • 對於str2,虛擬機先去String Pool裏尋找是否存在和“abc”相等的字符串對象,如果有,則將str2指向String pool中的字符串地址;
  • 對於str3,虛擬機直接在堆區創建一個對象,雖然str1已經創建了一個內容相同的對象,但是str4還是會創建一個對象,所以str1==str4返回false,因爲他們指向了不同的對象;
  • 對於str4,虛擬機會先去String pool尋找與“abc”內容相同的對象,發現存在了(如果之前沒有,str2也創建了),所以str4就直接指向了String Pool中的“abc”,所以str2==str4返回true;
  • 對於str5,會將字符串先進行表達式計算,然後放入字符串池中,即str2==str5返回true;
String ab = “ab”;
String c = “c”;
  • 對於變量的拼接或者變量和常量的拼接(ab+“c”),String類會按照new一個字符串的方式在堆區創建一個對象,即ab+c==str2返回false;

3、 對於String類的intern方法

String str6 = str1.intern();
  • Intern方法會返回一個將str1放入String Pool的指針(如果池中沒有,則加入),此時str2==str6會返回true;
  • 但是intern方法並不會改變str1的指針,即str1==str2依然返回false;
  • 該方法的實現是一個本地(native)方法;

4、String Pool

  • 對於字符串池,一般來說,當一個字符串進入到字符串池中,如果沒有了外部引用,也不會被垃圾回收,因爲字符串池不會被垃圾回收,所以這樣可能會導致內存泄漏;
  • 在虛擬機中,這一塊稱爲String常量池的區間專門用於存放字符串常量。在JDK 1.6之前,這塊區間屬於永久區的一部分,但是在JDK 1.7以後,它就被移到了堆中進行管理。
  • 可以通過以下代碼測試:
public static void main(String[] args) {  
        List<String> list = new ArrayList<String>();  
        int i = 0;  
        while(true){  
            list.add(String.valueOf(i++).intern());  
        }  
    }  
//JVM參數設置爲:-Xmx5m -XX:MaxPermSize=5m
  • 當JDK版本大於1.7的時候,會報錯:java.lang.OutOfMemoryError: Java heap space
  • 而低於1.7的則會報錯:java.lang.OutOfMemoryError: PermGen space  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章