java 中String類的內存和equals與“=="的比較

    最近看javaSe基礎,被String類的equals方法和“==”搞懵逼了,類似的題目總是搞不到,覺得好好花點時間把這個問題搞清楚,寫下自己的心得。如有錯誤,還望各位指正!

一、String類生成對象的內存問題。

字符串在內存通常分配在內存的兩個位置,一個是常量區,一個是在堆內存中。

第一種形式: String  str ="abc";

這句話是在字符串常量區創建一個“abc”的對象,str爲這個對象的引用。如果再來一句String str2 =“abc”,這是JVM並不是重新又創建一個新的對象,而是先在字符串常量池中看有沒有這個對象,若有,將str2指向字符串“abc”;若沒有才會重新創建。我們可以通過System.out.println(str1==str2)來判斷str1和str2是指向同一個引用。

類似String s ="abc"+“edf”也經常碰見。s 也是在字符串常量池中。JVM會先在字符串常量池中查找字符串“abc”和“edf”,沒有則重新創建,有則直接引用,然後會在字符串常量池中生成新的字符串“abcedf”;

第二種形式:String s =new String("abc");

這種形式是利用String類的構造器方法在堆內存中創建對象。JVM 首先會在字符串常量池中找“abc",有則直接引用,沒有則創建。然後將該對象複製到堆內存中。s指向該對象的內存。由於堆內存中的每個對象內存地址不同,所以String s1 =new String("abc")

和String s2=new String("abc")是兩個不同的對象,我們用System.out.println(s1==s2)可以判斷它們是兩個不同的對象。

二、equals方法和== 的區別。

“==”是直接比較兩個對象的地址。我們上面判斷字符串是否是同一個對象就是用的“==”方法。equals方法是Object對象的方法,我們可以看下Object類中equals方法的源碼:

 public boolean equals(Object obj) {
        return (this == obj);
    }

我們可以看到,它其實就是調用了“==”,Object對象的equals方法就是比較兩個對象的內存地址,相同返回true,否則返回false。而String類是Object類的之類,但是String類繼承Object類之後重寫了它的equals方法,源碼如下:

public boolean equals(Object anObject) {
        if (this == anObject) {
            return true;
        }
        if (anObject instanceof String) {
            String anotherString = (String)anObject;
            int n = value.length;
            if (n == anotherString.value.length) {
                char v1[] = value;
                char v2[] = anotherString.value;
                int i = 0;
                while (n-- != 0) {
                    if (v1[i] != v2[i])
                        return false;
                    i++;
                }
                return true;
            }
        }
        return false;
    }

我們可以看到,String類也是先比較兩個對象的地址,地址相同則直接返回true,如果不相同,則將傳入的對象轉換成字符串,再開始進行內容的比較,所以String類的equals方法我們可以認爲它是比較字符串的內容的。同理我們可以發現很多類都重寫了Object類的equals方法,那麼這時候的equals方法可能就不是比較對象的地址了。

總結:String類的對象一般存儲在字符串常量池和堆內存中,其中用new關鍵字的創建的對象在堆內存中。“==”是比較兩個對象的內存地址,Object類對象的equals方法就是比較對象的內存地址。由於Object類爲一切類的父類,所以如果類沒有重寫equals方法,那麼相當於它是調用的Object類的equals方法,比較的是對象的內存地址。重寫了Object類的equals方法的類,該方法比較的內容就要看具體的實現了。







發佈了32 篇原創文章 · 獲贊 19 · 訪問量 6萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章