題外話: JAVA 編程,一切皆對象。那麼面試的時候就會有人問,java所有類的基類(又叫做根類)是什麼?如果連這個都答不上來,確實有點尷尬,即使你知道所有的類都可以向上轉型爲Object類。答案其實很簡單,就是今天要講的Object類,它是類層次結構的根類 。
java.lang.Object
public class Object類 Object 是類層次結構的根類(所有類的基類)。每個類都使用 Object 作爲超類。所有對象(包括數組)都實現這個類的方法。
構造方法摘要 |
Object() |
方法摘要 |
|
protected Object |
clone() 創建並返回此對象的一個副本。 |
boolean |
equals(Object obj) 指示其他某個對象是否與此對象“相等”。 |
protected void |
finalize() 當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。 |
Class<?> |
getClass() 返回此 Object 的運行時類。 |
int |
hashCode() 返回該對象的哈希碼值。 |
void |
notify() 喚醒在此對象監視器上等待的單個線程。 |
void |
notifyAll() 喚醒在此對象監視器上等待的所有線程。 |
String |
toString() 返回該對象的字符串表示。 |
void |
wait() 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法前,導致當前線程等待。 |
void |
wait(long timeout) 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者超過指定的時間量前,導致當前線程等待。 |
void |
wait(long timeout, int nanos) 在其他線程調用此對象的 notify() 方法或 notifyAll() 方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量前,導致當前線程等待。 |
構造方法詳細信息
Object
public Object()
方法詳細信息
getClass
public final Class<?> getClass()
返回此 Object
的運行時類。返回的 Class
對象是由所表示類的 static synchronized
方法鎖定的對象。
實際結果類型是 Class<? extends |X|>,其中 |X| 表示清除表達式中的靜態類型,該表達式調用 getClass。 例如,以下代碼片段中不需要強制轉換:
Number n = 0;
Class<? extends Number> c = n.getClass();
返回:
表示此對象運行時類的 Class
對象。
hashCode
public int hashCode()
返回該對象的哈希碼值。支持此方法是爲了提高哈希表(例如 java.util.Hashtable
提供的哈希表)的性能。
hashCode 的常規協定是:
- 在 Java 應用程序執行期間,在對同一對象多次調用 hashCode 方法時,必須一致地返回相同的整數,前提是將對象進行 equals 比較時所用的信息沒有被修改。從某一應用程序的一次執行到同一應用程序的另一次執行,該整數無需保持一致。
- 如果根據 equals(Object) 方法,兩個對象是相等的,那麼對這兩個對象中的每個對象調用 hashCode 方法都必須生成相同的整數結果。
- 如果根據 equals(java.lang.Object) 方法,兩個對象不相等,那麼對這兩個對象中的任一對象上調用 hashCode 方法不 要求一定生成不同的整數結果。但是,程序員應該意識到,爲不相等的對象生成不同整數結果可以提高哈希表的性能。
實際上,由 Object 類定義的 hashCode 方法確實會針對不同的對象返回不同的整數。(這一般是通過將該對象的內部地址轉換成一個整數來實現的,但是 JavaTM 編程語言不需要這種實現技巧。)
返回:
此對象的一個哈希碼值。
equals
public boolean equals(Object obj)
指示其他某個對象是否與此對象“相等”。
equals 方法在非空對象引用上實現相等關係:
- 自反性:對於任何非空引用值 x,x.equals(x) 都應返回 true。
- 對稱性:對於任何非空引用值 x 和 y,當且僅當 y.equals(x) 返回 true 時,x.equals(y) 才應返回 true。
- 傳遞性:對於任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,並且 y.equals(z) 返回 true,那麼 x.equals(z) 應返回 true。
- 一致性:對於任何非空引用值 x 和 y,多次調用 x.equals(y) 始終返回 true 或始終返回 false,前提是對象上 equals 比較中所用的信息沒有被修改。
- 對於任何非空引用值 x,x.equals(null) 都應返回 false。
Object 類的 equals 方法實現對象上差別可能性最大的相等關係;即,對於任何非空引用值 x 和 y,當且僅當 x 和 y 引用同一個對象時,此方法才返回 true(x == y 具有值 true)。
注意:當此方法被重寫時,通常有必要重寫 hashCode 方法,以維護 hashCode 方法的常規協定,該協定聲明相等對象必須具有相等的哈希碼。
參數:
obj
- 要與之比較的引用對象。
返回:
如果此對象與 obj 參數相同,則返回 true
;否則返回 false
。
clone
protected Object clone()
throws CloneNotSupportedException
創建並返回此對象的一個副本。“副本”的準確含義可能依賴於對象的類。這樣做的目的是,對於任何對象 x,表達式:
x.clone() != x
爲 true,表達式:
x.clone().getClass() == x.getClass()
也爲 true,但這些並非必須要滿足的要求。一般情況下:
x.clone().equals(x)
爲 true,但這並非必須要滿足的要求。
按照慣例,返回的對象應該通過調用 super.clone 獲得。如果一個類及其所有的超類(Object 除外)都遵守此約定,則 x.clone().getClass() == x.getClass()。
按照慣例,此方法返回的對象應該獨立於該對象(正被複制的對象)。要獲得此獨立性,在 super.clone 返回對象之前,有必要對該對象的一個或多個字段進行修改。這通常意味着要複製包含正在被複制對象的內部“深層結構”的所有可變對象,並使用對副本的引用替換對這些對象的引用。如果一個類只包含基本字段或對不變對象的引用,那麼通常不需要修改 super.clone 返回的對象中的字段。
Object 類的 clone 方法執行特定的複製操作。首先,如果此對象的類不能實現接口 Cloneable,則會拋出 CloneNotSupportedException。注意,所有的數組都被視爲實現接口 Cloneable。否則,此方法會創建此對象的類的一個新實例,並像通過分配那樣,嚴格使用此對象相應字段的內容初始化該對象的所有字段;這些字段的內容沒有被自我複製。所以,此方法執行的是該對象的“淺表複製”,而不“深層複製”操作。
Object 類本身不實現接口 Cloneable,所以在類爲 Object 的對象上調用 clone 方法將會導致在運行時拋出異常。
返回:
此實例的一個副本。
拋出:
CloneNotSupportedException
- 如果對象的類不支持 Cloneable
接口,則重寫 clone
方法的子類也會拋出此異常,以指示無法複製某個實例。
toString
public String toString()
返回該對象的字符串表示。通常, toString
方法會返回一個“以文本方式表示”此對象的字符串。結果應是一個簡明但易於讀懂的信息表達式。建議所有子類都重寫此方法。
Object 類的 toString 方法返回一個字符串,該字符串由類名(對象是該類的一個實例)、at 標記符“@”和此對象哈希碼的無符號十六進制表示組成。換句話說,該方法返回一個字符串,它的值等於:
getClass().getName() + '@' + Integer.toHexString(hashCode())
返回:
該對象的字符串表示形式。
notify
public final void notify()
喚醒在此對象監視器上等待的單個線程。如果所有線程都在此對象上等待,則會選擇喚醒其中一個線程。選擇是任意性的,並在對實現做出決定時發生。線程通過調用其中一個 wait
方法,在對象的監視器上等待。
直到當前線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程。被喚醒的線程將以常規方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作爲鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。
此方法只應由作爲此對象監視器的所有者的線程來調用。通過以下三種方法之一,線程可以成爲此對象監視器的所有者:
- 通過執行此對象的同步實例方法。
- 通過執行在此對象上進行同步的 synchronized 語句的正文。
- 對於 Class 類型的對象,可以通過執行該類的同步靜態方法。
一次只能有一個線程擁有對象的監視器。
拋出:
IllegalMonitorStateException
- 如果當前線程不是此對象監視器的所有者。
notifyAll
public final void notifyAll()
喚醒在此對象監視器上等待的所有線程。線程通過調用其中一個 wait
方法,在對象的監視器上等待。
直到當前線程放棄此對象上的鎖定,才能繼續執行被喚醒的線程。被喚醒的線程將以常規方式與在該對象上主動同步的其他所有線程進行競爭;例如,喚醒的線程在作爲鎖定此對象的下一個線程方面沒有可靠的特權或劣勢。
此方法只應由作爲此對象監視器的所有者的線程來調用。有關線程能夠成爲監視器所有者的方法的描述,請參閱 notify 方法。
拋出:
IllegalMonitorStateException
- 如果當前線程不是此對象監視器的所有者。
wait
public final void wait(long timeout)
throws InterruptedException
在其他線程調用此對象的 notify()
方法或 notifyAll()
方法,或者超過指定的時間量前,導致當前線程等待。
當前線程必須擁有此對象監視器。
此方法導致當前線程(稱之爲 T)將其自身放置在對象的等待集中,然後放棄此對象上的所有同步要求。出於線程調度目的,在發生以下四種情況之一前,線程 T 被禁用,且處於休眠狀態:
- 其他某個線程調用此對象的 notify 方法,並且線程 T 碰巧被任選爲被喚醒的線程。
- 其他某個線程調用此對象的 notifyAll 方法。
- 其他某個線程中斷線程 T。
- 大約已經到達指定的實際時間。但是,如果 timeout 爲零,則不考慮實際時間,在獲得通知前該線程將一直等待。
然後,從對象的等待集中刪除線程 T,並重新進行線程調度。然後,該線程以常規方式與其他線程競爭,以獲得在該對象上同步的權利;一旦獲得對該對象的控制權,該對象上的所有其同步聲明都將被恢復到以前的狀態,這就是調用 wait 方法時的情況。然後,線程 T 從 wait 方法的調用中返回。所以,從 wait 方法返回時,該對象和線程 T 的同步狀態與調用 wait 方法時的情況完全相同。
在沒有被通知、中斷或超時的情況下,線程還可以喚醒一個所謂的虛假喚醒 (spurious wakeup)。雖然這種情況在實踐中很少發生,但是應用程序必須通過以下方式防止其發生,即對應該導致該線程被提醒的條件進行測試,如果不滿足該條件,則繼續等待。換句話說,等待應總是發生在循環中,如下面的示例:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout);
... // Perform action appropriate to condition
}
如果當前線程在等待之前或在等待時被任何線程中斷,則會拋出 InterruptedException。在按上述形式恢復此對象的鎖定狀態時纔會拋出此異常。
注意,由於 wait 方法將當前線程放入了對象的等待集中,所以它只能解除此對象的鎖定;可以同步當前線程的任何其他對象在線程等待時仍處於鎖定狀態。
此方法只應由作爲此對象監視器的所有者的線程來調用。有關線程能夠成爲監視器所有者的方法的描述,請參閱 notify 方法。
參數:
timeout
- 要等待的最長時間(以毫秒爲單位)。
拋出:
IllegalArgumentException
- 如果超時值爲負。
IllegalMonitorStateException
- 如果當前線程不是此對象監視器的所有者。
InterruptedException
- 如果在當前線程等待通知之前或者正在等待通知時,任何線程中斷了當前線程。在拋出此異常時,當前線程的 中斷狀態 被清除。
wait
public final void wait(long timeout,
int nanos)
throws InterruptedException
在其他線程調用此對象的 notify()
方法或 notifyAll()
方法,或者其他某個線程中斷當前線程,或者已超過某個實際時間量前,導致當前線程等待。
此方法類似於一個參數的 wait 方法,但它允許更好地控制在放棄之前等待通知的時間量。用毫微秒度量的實際時間量可以通過以下公式計算出來:
1000000*timeout+nanos
在其他所有方面,此方法執行的操作與帶有一個參數的 wait(long) 方法相同。需要特別指出的是,wait(0, 0) 與 wait(0) 相同。
當前線程必須擁有此對象監視器。該線程發佈對此監視器的所有權,並等待下面兩個條件之一發生:
- 其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監視器上等待的線程醒來。
- timeout 毫秒值與 nanos 毫微秒參數值之和指定的超時時間已用完。
然後,該線程等到重新獲得對監視器的所有權後才能繼續執行。
對於某一個參數的版本,實現中斷和虛假喚醒是有可能的,並且此方法應始終在循環中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait(timeout, nanos);
... // Perform action appropriate to condition
}
此方法只應由作爲此對象監視器的所有者的線程來調用。有關線程能夠成爲監視器所有者的方法的描述,請參閱 notify
方法。
參數:
timeout
- 要等待的最長時間(以毫秒爲單位)。
nanos
- 額外時間(以毫微秒爲單位,範圍是 0-999999)。
拋出:
IllegalArgumentException
- 如果超時值是負數,或者毫微秒值不在 0-999999 範圍內。
IllegalMonitorStateException
- 如果當前線程不是此對象監視器的所有者。
InterruptedException
- 如果在當前線程等待通知之前或者正在等待通知時,任何線程中斷了當前線程。在拋出此異常時,當前線程的 中斷狀態 被清除。
wait
public final void wait()
throws InterruptedException
在其他線程調用此對象的 notify()
方法或 notifyAll()
方法前,導致當前線程等待。換句話說,此方法的行爲就好像它僅執行 wait(0) 調用一樣。
當前線程必須擁有此對象監視器。該線程發佈對此監視器的所有權並等待,直到其他線程通過調用 notify 方法,或 notifyAll 方法通知在此對象的監視器上等待的線程醒來。然後該線程將等到重新獲得對監視器的所有權後才能繼續執行。
對於某一個參數的版本,實現中斷和虛假喚醒是可能的,而且此方法應始終在循環中使用:
synchronized (obj) {
while (<condition does not hold>)
obj.wait();
... // Perform action appropriate to condition
}
此方法只應由作爲此對象監視器的所有者的線程來調用。有關線程能夠成爲監視器所有者的方法的描述,請參閱 notify
方法。
拋出:
IllegalMonitorStateException
- 如果當前線程不是此對象監視器的所有者。
InterruptedException
- 如果在當前線程等待通知之前或者正在等待通知時,任何線程中斷了當前線程。在拋出此異常時,當前線程的 中斷狀態 被清除。
finalize
protected void finalize()
throws Throwable
當垃圾回收器確定不存在對該對象的更多引用時,由對象的垃圾回收器調用此方法。子類重寫 finalize
方法,以配置系統資源或執行其他清除。
finalize 的常規協定是:當 JavaTM 虛擬機已確定尚未終止的任何線程無法再通過任何方法訪問此對象時,將調用此方法,除非由於準備終止的其他某個對象或類的終結操作執行了某個操作。finalize 方法可以採取任何操作,其中包括再次使此對象對其他線程可用;不過,finalize 的主要目的是在不可撤消地丟棄對象之前執行清除操作。例如,表示輸入/輸出連接的對象的 finalize 方法可執行顯式 I/O 事務,以便在永久丟棄對象之前中斷連接。
Object 類的 finalize 方法執行非特殊性操作;它僅執行一些常規返回。Object 的子類可以重寫此定義。
Java 編程語言不保證哪個線程將調用某個給定對象的 finalize 方法。但可以保證在調用 finalize 時,調用 finalize 的線程將不會持有任何用戶可見的同步鎖定。如果 finalize 方法拋出未捕獲的異常,那麼該異常將被忽略,並且該對象的終結操作將終止。
在啓用某個對象的 finalize 方法後,將不會執行進一步操作,直到 Java 虛擬機再次確定尚未終止的任何線程無法再通過任何方法訪問此對象,其中包括由準備終止的其他對象或類執行的可能操作,在執行該操作時,對象可能被丟棄。
對於任何給定對象,Java 虛擬機最多隻調用一次 finalize 方法。
finalize 方法拋出的任何異常都會導致此對象的終結操作停止,但可以通過其他方法忽略它。
拋出:
Throwable
- 此方法拋出的 Exception