Object類
是類層次結構的根。 每個類都有Object
作爲超類。 所有對象(包括數組)都實現了這個類的方法。
源碼:
package java.lang;
public class Object {
/**
* 說明:
* registerNatives函數前面有native關鍵字修飾,Java中,
* 用native關鍵字修飾的函數表明該方法的實現並不是在Java中去完成,
* 而是由C/C++去完成,並被編譯成了.dll,由Java去調用。方法的具體實現體在dll文件中,
* 對於不同平臺,其具體實現應該有所不同。用native修飾,即表示操作系統,需要提供此方法,
* Java本身需要使用。具體到registerNatives()方法本身,
* 其主要作用是將C/C++中的方法映射到Java中的native方法,實現方法命名的解耦。
*/
private static native void registerNatives();
//靜態代碼塊
static {
registerNatives();
}
/**
* 說明:
* 返回object運行時的類
* @return
*/
public final native Class<?> getClass();
/**
* 說明:
* 返回對象的哈希值、通過哈希(散列)函數得到
*
* 常見Hash函數有以下幾個:
* 1、直接定址法:直接以關鍵字k或者k加上某個常數(k+c)作爲哈希地址。
* 2、數字分析法:提取關鍵字中取值比較均勻的數字作爲哈希地址。
* 3、除留餘數法:用關鍵字k除以某個不大於哈希表長度m的數p,將所得餘數作爲哈希表地址。
* 4、分段疊加法:按照哈希表地址位數將關鍵字分成位數相等的幾部分,
* 其中最後一部分可以比較短。然後將這幾部分相加,捨棄最高進位後的結果就是該關鍵字的哈希地址。
* 5、平方取中法:如果關鍵字各個部分分佈都不均勻的話,可以先求出它的平方值,然後按照需求取中間的幾位作爲哈希地址。
* 6、僞隨機數法:採用一個僞隨機數當作哈希函數。
*
* 常見的解決碰撞的方法:
*1、開放定址法:開放定址法就是一旦發生了衝突,就去尋找下一個空的散列地址,
* 只要散列表足夠大,空的散列地址總能找到,並將記錄存入。
* 2、鏈地址法:將哈希表的每個單元作爲鏈表的頭結點,所有哈希地址爲i的元素構成一個同義詞鏈表。
* 即發生衝突時就把該關鍵字鏈在以該單元爲頭結點的鏈表的尾部。
* 3、再哈希法:當哈希地址發生衝突用其他的函數計算另一個哈希函數地址,直到衝突不再產生爲止。
* 4、建立公共溢出區:將哈希表分爲基本表和溢出表兩部分,發生衝突的元素都放入溢出表中。
* @return
*/
public native int hashCode();
/**
* 說明:
* 用來比較方法兩個對象的內容是否相等。不能用於基本數據比較
* 區別:
* ==:如果比較的對象是基本數據類型,則比較的是數值是否相等;如果比較的是引用數據類型,
* 則比較的是對象的地址值是否相等。
* @param obj
* @return
*/
public boolean equals(Object obj) {
return (this == obj);
}
/**
* 說明:
* 創建並返回此對象的副本。重新在堆裏創建一個對象、棧內地址也不一樣。
* 淺拷貝:如果兩個Person 對象的name 的地址值相同, 說明兩個對象的name 都指向同一個String 對象
* 深拷貝:而如果兩個Person對象的name 的地址值不同, 那麼就說明指向不同的String 對象,
* @return
* @throws CloneNotSupportedException
*/
protected native Object clone() throws CloneNotSupportedException;
/**
* 說明:
* 返回對象的字符串表示形式
*Integer.toHexString()//返回字符串表示的16進制數(無符號)
* @return
*/
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
/**
* 說明:
* 喚醒正在等待對象監視器的單個線程。
*/
public final native void notify();
/**
* 說明:
* 喚醒正在等待對象監視器的所有線程。
*/
public final native void notifyAll();
/**
* 說明:
* 調用wait()方法的時候,線程會放棄對象鎖,進入等待此對象的等待池中,
(進入等待隊列,也就是阻塞的一種,叫等待阻塞)同時釋放對象鎖,並讓出CPU資源
* 傳入參數就是在參數結束的時間後開始等待,不穿如參數就是直接等待。
* wait()使用notify()方法、notiftAll()方法或者等待指定時間來喚醒當前等待池中的線程。
等待的線程只是被激活,
* 但是必須得再次獲得鎖才能繼續往下執行,也就是說只要鎖沒被釋放,
原等待線程因爲爲獲取鎖仍然無法繼續執行。
* notify的作用只負責喚醒線程,線程被喚醒後有權利重新參與線程的調度。
*區別:sleep()
* sleep()方法是線程類(Thread)的靜態方法,讓調用的線程進入指定時間睡眠狀態,
使得當前線程進入阻塞狀態,
* 告訴系統至少在指定時間內不需要爲線程調度器爲該線程分配執行時間片,給執行機會給其他線程
* (實際上,調用sleep()方法時並不要求持有任何鎖,即sleep()可在任何地方使用。),
但是監控狀態依然保持,到時後會自動恢復。
*
* @param timeout
* @throws InterruptedException
* 如果拋出 InterruptedException 意味着一個方法是阻塞方法
* IllegalArgumentException - 如果超時值是負數,或者毫微秒值不在 0-999999 範圍內。
* IllegalMonitorStateException - 如果當前線程不是此對象監視器的所有者。
* InterruptedException - 如果在當前線程等待通知之前或者正在等待通知時,任何線程中斷了當前線程。在拋出此異常時,當前線程的 中斷狀態 被清除。(中斷異常)
*
* wait(0, 0) 與 wait(0) 相同
*/
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);
}
/**
* 說明:
* Object 類的一個方法,在垃圾回收器執行的時候會調用被回收對象的此方法,可以覆蓋此方法
* 提供垃圾收集時的其他資源回收、這是一個被動的方法(其實就是回調方法),不需要我們調用。
* @throws Throwable
*/
protected void finalize() throws Throwable { }
}
總結:常用方法
getClass:獲得運行時類
hashCode:獲取hash值
equals:比較對象內容是否相等
wait:放棄鎖、阻塞等待
notify:喚醒線程
notifyAll:喚醒全部線程