深入學習java原始碼——Object類
Object class原始碼解析
當我們從jdk包中剛取出來看Object的原始檔時,感覺檔案內容好多哈,其實真正的程式碼沒有多少,大多是註釋,看下面我把註釋全刪了,看起來是不是更加直觀了。
package java.lang;
public class Object {
private static native void registerNatives();
static {
registerNatives();
}
public final native Class<?> getClass();
public native int hashCode();
public boolean equals(Object obj) {
return (this == obj);
}
protected native Object clone() throws CloneNotSupportedException;
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
public final native void notify();
public final native void notifyAll();
public final native void wait(long timeout) throws InterruptedException;
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative" );
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
public final void wait() throws InterruptedException {
wait(0);
}
protected void finalize() throws Throwable { }
}
原始碼通讀
以下原始碼中涉及到的native方法底層均為c/c++語言實現,檢視c/c++語言原始碼請訪問 AndroidXRef網站 檢視 1、registerNatives方法解析
//private static native修飾的方法表示私有的、本地必須實現的原生方法,
//所以我們java開發人員不必擔心此類方法的實現,因為底層已經為我們用C語言實現。
private static native void registerNatives();
static {//靜態程式碼塊表示類載入時執行此方法
registerNatives();
}
2、getClass方法解析
//作業系統底層實現,且不被其他子類所覆蓋
//getClass表示獲取物件執行時的類定義資訊
public final native Class<?> getClass();
3、hashCode方法解析
//返回物件的hashCode值
public native int hashCode();
4、equals方法解析
/**
*比較兩個物件是否相等,相等返回true,不相等返回false。
*Object作為java中所有類的父類,其實此方法是有侷限性的,我們大多時候需要重寫該
*方法來達到兩個物件的比較;
*我們知道所有的物件都擁有引用(記憶體地址)和狀態(資料),同時“==”比較兩個物件的的內
*存地址,所以說使用Object的equals()方法是比較兩個物件的記憶體地址是否相等,即若
*object1.equals(object2)為true,則表示object1和object2實際上是引用同一個物件。
*在JDK中,String、Math等封裝類都對equals()方法進行了重寫。
*/
public boolean equals(Object obj) {
return (this == obj);
}
//被其他類重寫後的equals方法,可以看到物件內容的比較
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String)anObject;
int n = count;
if (n == anotherString.count) {
char v1[] = value;
char v2[] = anotherString.value;
int i = offset;
int j = anotherString.offset;
while (n-- != 0) {
if (v1[i++] != v2[j++])
return false;
}
return true;
}
}
return false;
}
5、clone方法解析
//複製物件方法,返回一個新的物件,在該物件的類無法實現 Cloneable 介面時,丟擲該異常。
//重寫 clone 方法的應用程式也可能丟擲此異常,指示不能或不應複製一個物件。
//這裡要注意與物件引用的賦值區分,如Object a1 = new Object(); Object a2 = a1; 其實還是同一個物件。
protected native Object clone() throws CloneNotSupportedException;
6、toString方法解析
/**
*該方法這裡返回 當前物件名@此物件雜湊碼的無符號十六進位制表示形式。
*Integer.toHexString(hashCode()) 以物件的雜湊碼為引數,以16進位制無符號整數形式返回此雜湊碼的字串
*表示形式。一般在其他類中都會重寫、過載此方法。
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
7、notify方法解析
//其API解釋為 喚醒在此物件監視器上等待的單個執行緒。
//也就是在執行此方法時隨機選擇一個在該物件上呼叫wait方法的執行緒,解除其阻塞狀態。
public final native void notify();
8、notifyAll方法解析
//其API解釋為 喚醒在此物件監視器上等待的所有執行緒。
public final native void notifyAll();
9、 wait方法解析
//在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法前,導致當前執行緒等待。
public final void wait() throws InterruptedException {
wait(0);
}
//在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量timeout前,
//導致當前執行緒等待。
public final native void wait(long timeout) t hrows InterruptedException;
//在其他執行緒呼叫此物件的 notify() 方法或 notifyAll() 方法,或者其他某個執行緒中斷當前執行緒,
//或者已超過某個實際時間量timeout前,導致當前執行緒等待。
public final void wait(long timeout, int nanos) throws InterruptedException {
if (timeout < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (nanos < 0 || nanos > 999999) {
throw new IllegalArgumentException(
"nanosecond timeout value out of range");
}
if (nanos > 0) {
timeout++;
}
wait(timeout);
}
10、finalize方法解析
//當垃圾回收器確定不存在對該物件的更多引用時,由物件的垃圾回收器呼叫此方法。
//子類重寫 finalize 方法,以配置系統資源或執行其他清除。
protected void finalize() throws Throwable { }
學完啦,放鬆一下吧!
-
笑話一:“我給你出個腦筋急轉彎,你說達芬奇密碼的上面是什麼?” “這……太難了吧。不知道。” “笨!達芬奇密碼的上面就是達芬奇帳號啊,那達芬奇密碼的下面是什麼?”“我……這……還是不知道。”“是達芬奇驗證碼”。
-
笑話二:【程式設計師被提bug之後的反應】 1.怎麼可能;2.在我這是好的,不信你來看看;3.真是奇怪,剛剛還好好的;4.肯定是資料問題;5.你清下快取試試;6.重啟下電腦試試;7.你裝的什麼版本的類庫(jdk)8.這誰寫的程式碼;9.尼瑪怎麼還在用360安全瀏覽器;10.使用者不會像你這麼操作的。
-
笑話三:客戶被綁,矇眼,驚問:“想幹什麼?” 對方不語,鞭笞之,客戶求饒:“別打,要錢?” 又一鞭,“十萬夠不?” 又一鞭,“一百萬?” 又一鞭。客戶崩潰:“你們TMD到底要啥?” “要什麼?我幫你做專案,寫程式碼的時候也很想知道你TMD到底想要啥!”
-
笑話四:程式猿跟產品經理一起看電視。每個節目看到一半程式猿就換臺,看到一半就換臺,幾次之後產品經理終於忍無可忍的咆哮:老子剛看出點意思你就換、剛看出點意思你就換,到底還讓不讓人看啦?! 程式猿淡定的盯著電視道:你半路改需求的時候我可沒吱過聲!
-
笑話五:程式猿的情書 親愛的“物件”: 我能抽象出整個世界,但是我不能抽象出你,因為你在我心中是那麼的具體,所以我的世界並不完整。 我可以過載甚至覆蓋這個世界裡的任何一種方法,但是我卻不能過載對你的思念,也許命中註定了,你在我的世界裡永遠的烙上了靜態的屬性。 而我不慎呼叫了愛你這個方法,當我義無返顧的把自己作為引數傳進這個方法時,我才發現愛上你是一個死迴圈,它不停的返回對你的思念,記在我心裡的堆疊,在這無盡的黑夜中,我的記憶體裡已經再也裝不下別人。 我不停的向系統申請空間,但卻捕獲一個異常:我愛的人不愛我。 為了解決這個異常,我願意虛擬出最後一點記憶體,把所有我能實現的方法地址記入堆疊,並且在棧尾存入最後一個方法:將字串“我愛你,你愛我嗎?”傳遞給你。 如果返回值為真,我將用盡一生去愛你,否則,我將釋放掉所有系統資源。