JDK源碼之Object
1、Object類簡介
java中所有的類都會繼承Object類,屬于java.lang包。
Object類提供的方法如下:其中registerNatives()、getClass()、hashCode()、clone()、notify()、notifyAll()、wait(long timeout)為native方法,后面挑幾個重要的方法講一下。
native 為java的一個關鍵字
JNI:Java Native Interface ,從Java1.1開始,JNI標準成為java平臺的一部分,它允許Java代碼和其他語言寫的代碼進行交互,例如C或者C++代碼。

2、源碼
2.1、getClass方法
public final native Class<?> getClass();
getClass()方法返回對象運行時類。
2.2、hashCode方法
public native int hashCode();
hashCode()返回對象的hash值,為int類型。那么對象創建好之后何時計算hashCode值?計算出的hashCode的值存放在那里呢?那么我們來看一下一個java對象組成 。

對象由對象頭(對象頭包括Mark Word 和 Class Pointer類型指針)、實例數據、對齊填充部分組成,數組對象比較特殊,會多數組長度部分。對齊填充部分時為了保證對象的大小是8字節的整數倍。
對象頭中Mark Word用于存儲對象自身的一些數據,具體存儲信息如下圖所示,對象頭的大小在不同的虛擬機上的大小有所差異,通常為32bit或者64bit。
對象的hashCode值是在對象使用時調用hashCode函數時計算,并不是對象創建時就計算好的。


2.3、equals方法
public boolean equals(Object obj) { return (this == obj); }
由源碼可以看出,在Object這個類中,equals()方法和==是相同的,比較的是兩個對象的引用是否相同。
我們比較兩個字符串是否相等時,需要比較字符串本身的內容是否相等,而不希望比較字符串的引用地址是否相同,所有String類重寫了equals()方法,讓我一起看看源碼。
public boolean equals(Object anObject) { if (this == anObject) { //如果引用的地址相同,那么這兩個字符串必然相同,直接返回true return true; } if (anObject instanceof String) {//判斷對象是否為String類型 String anotherString = (String)anObject;//強轉為String對象 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; //有一個不相同則返回false i++; } return true; //內容完全,返回true } } return false; //不是String對象直接返回false }
如果在程序開發中需要比較對象的屬性值是否相同,應該重寫Object的equals方法,否則會調用Object的equals方法,使用==比較兩個對象引用地址是否相同。
2.4、clone方法
protected native Object clone() throws CloneNotSupportedException;
該方法實現對象的淺拷貝,使用clone()方法時,記得捕獲CloneNotSupportedException異常,或者在類上實現Cloneable接口但不拋出該異常(盡管這在實際操作中不常見)。此外,使用clone()方法時要小心,因為它可能會導致性能問題或者在復雜對象圖中出現問題(比如循環引用)。在Java中,通常推薦使用構造器或拷貝構造函數來實現淺拷貝或深拷貝,特別是在處理復雜對象時。。
淺拷貝(Shallow Copy)指的是創建一個新的對象,然后將原始對象的數據(字段)復制到新對象中。如果原始對象的字段是值類型(如int、double等基本數據類型,或者它們的包裝類如Integer、Double等),這些值會被復制到新對象中。如果原始對象的字段是引用類型(如對象、數組等),那么這些引用類型的字段不會被復制其內容,而是復制引用本身的地址。這意味著新的對象和原始對象將引用同一個內存地址。
深拷貝:不僅復制對象本身,還遞歸地復制對象內部引用的所有對象。這意味著原始對象和副本對象不會共享任何引用指向的對象。
2.5、finalize方法
protected void finalize() throws Throwable { }
當一個Java對象被垃圾回收器標記為不再使用時,垃圾回收器會調用對象的finalize()方法來清理這個對象。但是垃圾回收器并不保證會立馬調用該方法,可能會在后面某個何時的時間再調用。

浙公網安備 33010602011771號