Java記憶體分配及equals和 號的詳細講解

2021-06-22 01:53:19 字數 2775 閱讀 6985

從圖中我們可以很清晰的看出,程式通重載入器從硬碟中載入到記憶體中,並且儲存到不同的位置,通俗的說就是new出來的東西存放在heap(堆區),區域性變數存放在stack(棧區),靜態變數和字串常量存放在data segment(資料段)中,邏輯**存放在code segment(**段)中

通過下面的**來解釋變數存放的位置:

class a

}public class myjvm

}

理解了上面的記憶體分配下面我們來**一下equals()方法:

object類的equals()方法簡介:

1:所有的類都從object類中繼承了equals()方法

2:object類中的equals()方法原始碼:

public boolean equals(object obj)
從原始碼可以看出object中的equals()方法是直接判斷this和obj本身的值是否相等,即用來判斷呼叫equals()的物件和形參obj所引用的物件是否是同一物件,所謂的同一物件就是指記憶體中同一塊儲存單元,只有內容相同且記憶體單元相同才會返回true,否則就返回false。

為什麼要重寫equals()方法或者說何時應該重寫equals()方法!

從object中equals()的原始碼可以看出要使兩個物件相等必須內容相等且記憶體位址也相同,但是現實生活中很多時候只要內容相同,我們就認為這兩個物件相等,很明顯,原生態的equals()方法是無法滿足我們需求的,這個時候我們就需要重寫equals()方法,使得只要兩個物件的內容相同,那麼這兩個物件就相同。

總而言之:如果希望不同記憶體但內容相同的兩個物件的相等時,我們就需要重寫equals()方法。

我們通過乙個例子來理解:

class a

public a(int id) }

public class myjvm else

}}

程式的輸出結果是a1和a2不相等。原因是因為雖然他們的內容一樣都是2,但是他們在記憶體中的位址不一樣,是兩個不同的物件。

修改程式【重寫父類equals()方法】:

class a 

public a(int id)

/*重寫父類的equals()方法*/

public boolean equals(object obj) else }}

public class myjvm else

}}

我們再來看乙個demo:

public class stringequalstest 

}

很多人都會以為上述程式的輸出結果會是false,理由很簡單嘛,因為這是兩個物件,雖然內容一樣,但是在記憶體中的位址並不一樣,你要是這麼想,恭喜你,說明你掌握了equals()方法的比較原理。但是很遺憾的告訴你,輸出結果是true,即str1和str2相等,原因也很簡單:string類內部已經實現了equals()方法,這下應該明白了吧,其實像string類、integer類、double類內部都已經實現equals()方法,不需要我們再去實現了。

說完了equals()方法,我們再來看看另乙個比較兩個物件是否相等的工具:等號"=="

== 比較的是兩個物件的內容和在記憶體中的存放位址是否相等,只有兩者都相等時才會返回true,否則返回false。

如下**:

public class stringequalstest 

}

根據我們剛才說的"=="的比較原理,輸出結果顯然是false,也是在我們預料之中的。因為這兩個物件在記憶體中的位址不一樣嘛。

我們再來看乙個例子:

public class stringequalstest 

}

很多人會以為上述程式的輸出結果會是false,因為他們在記憶體中的位址不一樣嘛,但是很遺憾,程式的輸出結果是true,str1 == str2;

至於原因嘛,我們還得回到文章開頭提到不同內容在記憶體中的儲存位置,根據文章開頭那個圖我們可以看出,str1和str2是存在棧區的,因為他們屬於區域性變數嘛,然而字串"abc"呢?它是存在堆區嗎?呵呵...不是啊!!!!字串"china"存放的位置是data segment【資料區域】,他們是同乙份拷貝,所以str1和str2指向的是同乙個內容。

上面這幅圖很好的體現了,為什麼 string str1 = new string("china")和string str2 = new string("china") 的str1不等於str2了,因為new string("china")是動態分配的,所以物件儲存在堆區,且儲存的位址不一致;

string str1 = "china" 和string str2 = "china" 的str1 等於str2 因為字串常量"china"是儲存在記憶體中的data segment【資料區】,且是同乙份拷貝。

下面說一下使用等號"=="比較物件的情景:

1:基本資料型別:byte,short,char,int,long,float,double,boolean 應用雙等號(==)比較他們的值。

2:在反射的的知識中比較兩個類的位元組碼是否相等我們也可以使用雙等號(==)

Java記憶體分配

大多數情況,物件在新生代eden區中分配。當eden去沒有足夠記憶體空間分配時,進行minor gc。大物件是指連續占用記憶體空間的物件,比如很長的字串以及陣列。用乙個年齡計數器,每次minor gc後存活的物件移動到survior空間,並且計數器加1.年齡計數器大於一定值 預設是15 將晉公升到老...

JAVA類記憶體分配

1 成員變數和區域性變數的區別 理解 1 在類中的位置不同 成員變數 類中方法外 區域性變數 方法定義中或者方法宣告上 2 在記憶體中的位置不同 成員變數 在堆中 區域性變數 在棧中 3 生命週期不同 成員變數 隨著物件的建立而存在,隨著物件的消失而消失 區域性變數 隨著方法的呼叫而存在,隨著方法的...

JAVA記憶體分配規則

物件分配規則 1.物件優先分配在eden 區,如果 eden 區沒有足夠的空間時,虛擬機器執行一次 minor gc。2.大物件直接進入老年代 大物件是指需要大量連續記憶體空間的物件 這樣做的目的是避免在eden 區和兩個 survivor 區之間發生大量的記憶體拷貝 新生代採用複製演算法收集記憶體...