Class Overview(類(lèi)概述)
這個(gè)類(lèi)是 Java 類(lèi)等級(jí)中的根牵囤。所有非初級(jí)的類(lèi)型(包括數(shù)組)都是直接或間接繼承這個(gè)類(lèi)。
按照以下這種風(fēng)格寫(xiě)一個(gè)規(guī)范的 <span id="equals">equals</span> 方法:
// Use @Override to avoid accidental overloading.
// 使用@Override 為了避免意外的過(guò)載
@Override public boolean equals(Object o) {
// Return true if the objects are identical.
// (This is just an optimization, not required for correctness.)
// 如果對(duì)象是相同的就返回 true
// (這僅僅是一種優(yōu)化批狐,并不要求正確性鳍寂。)
if (this == o) {
return true;
}
// Return false if the other object has the wrong type.
// This type may be an interface depending on the interface's specification.
// 如果另一個(gè)對(duì)象的類(lèi)型有誤,則返回 false
// 這種類(lèi)型可能是一個(gè)接口彼棍,取決于接口的規(guī)格
if (!(o instanceof MyType)) {
return false;
}
// Cast to the appropriate type.
// This will succeed because of the instanceof, and lets us access private fields.
// 轉(zhuǎn)換成適當(dāng)?shù)念?lèi)型
// 這將是成功的因?yàn)?o 是 Mytype 的實(shí)例惯雳,我們?cè)L問(wèn)私有字段
MyType lhs = (MyType) o;
// Check each field. Primitive fields, reference fields, and nullable reference
// fields are all treated differently.
// 檢查每一個(gè)字段朝巫。原始的字段,參考的字段石景,空引用的字段都被看成是不同的劈猿。
return primitiveField == lhs.primitiveField &&
referenceField.equals(lhs.referenceField) &&
(nullableField == null ? lhs.nullableField == null
: nullableField.equals(lhs.nullableField));
}
如果要重寫(xiě) equals 方法,同時(shí)也應(yīng)該重寫(xiě) hashCode 方法:相同的實(shí)例必須要有相同的哈希值潮孽。
參考 Effcetive Java 里的第 8 條揪荣,有更詳細(xì)的說(shuō)明。
按照以下這種風(fēng)格寫(xiě)一人規(guī)范的 <span id="hash" >hashCode</span> 方法:
@Override public int hashCode() {
// Start with a non-zero constant.
// 開(kāi)始于一個(gè)非零常數(shù)
int result = 17;
// Include a hash for each field.
// 包括每一個(gè)字段的哈希值
result = 31 * result + (booleanField ? 1 : 0);
result = 31 * result + byteField;
result = 31 * result + charField;
result = 31 * result + shortField;
result = 31 * result + intField;
result = 31 * result + (int) (longField ^ (longField >>> 32));
result = 31 * result + Float.floatToIntBits(floatField);
long doubleFieldBits = Double.doubleToLongBits(doubleField);
result = 31 * result + (int) (doubleFieldBits ^ (doubleFieldBits >>> 32));
result = 31 * result + Arrays.hashCode(arrayField);
result = 31 * result + referenceField.hashCode();
result = 31 * result +
(nullableReferenceField == null ? 0
: nullableReferenceField.hashCode());
return result;
}
如果不打算將您的類(lèi)型用作哈希鍵往史, 也不要只依賴(lài)于默認(rèn)的 hashCode 方法實(shí)現(xiàn)仗颈。因?yàn)檫@樣會(huì)不明顯的破壞將來(lái)任何一個(gè)把該類(lèi)型做為哈希鍵的編碼。應(yīng)該用拋異常的方法來(lái)替代:
@Override public int hashCode() {
throw new UnsupportedOperationException();
}
參考 Effective Java 第 9 條椎例,有更詳細(xì)的說(shuō)明挨决。
為了調(diào)試方便,按照以下的風(fēng)格重寫(xiě) <span id="toString"> toString </span>是很常見(jiàn)的:
@Override public String toString() {
return getClass().getName() + "[" +
"primitiveField=" + primitiveField + ", " +
"referenceField=" + referenceField + ", " +
"arrayField=" + Arrays.toString(arrayField) + "]";
}
包含的字段集一般與用 equals 方法測(cè)試的字段是一樣的订歪。
參考 Effective Java 第 10 條脖祈,有更詳細(xì)的說(shuō)明。
Public Constructors(公共構(gòu)造方法)
public Object()
構(gòu)造一個(gè)新的 Object 實(shí)例刷晋。
Public Methods(公共方法)
<span id="eq">public boolean equals(Object o)
</span>
比較該實(shí)例與指定的對(duì)象盖高,并且指示它們是否相同慎陵。為了相同,o 必須使用特定的類(lèi)比較來(lái)表示與此實(shí)例相同的對(duì)象喻奥。
通用約定是席纽,這種比較應(yīng)該是自反性,對(duì)稱(chēng)性撞蚕,傳遞性润梯。除了 null,沒(méi)有引用的對(duì)象等于 null甥厦。
僅僅當(dāng) this==o 的時(shí)候默認(rèn)返回 true仆救。如果想要實(shí)現(xiàn)自己的 equals 方法,參考寫(xiě)一個(gè)正確的 equals 方法矫渔。
對(duì)于 equals 方法和 hashCode 方法來(lái)說(shuō),通用約定是摧莽,如果兩個(gè)對(duì)象根據(jù) equals 方法比較是相等的庙洼,那么調(diào)用這兩個(gè)對(duì)象中任意一個(gè)對(duì)象的 hashCode 方法都必須產(chǎn)生同樣的整數(shù)結(jié)果。這就意味著镊辕,Object 的任意一個(gè)子類(lèi)通常這兩個(gè)方法都會(huì)復(fù)寫(xiě)油够,或者都不復(fù)寫(xiě)。
參數(shù)
o 與該實(shí)例比較的對(duì)象征懈。
返回值
如果指定的對(duì)象與該對(duì)象相同石咬,返回 true ,否則返回 false卖哎。
參考
public final Class<?> getClass()
返回一個(gè)唯一的 Class 實(shí)例鬼悠,表示這個(gè)對(duì)象的類(lèi)。注意亏娜,getClass()是一個(gè)特例焕窝,它事實(shí)上返回Class ,Foo 是對(duì)表達(dá)式類(lèi)型的擦除當(dāng) getClass()被調(diào)用時(shí)(這里我也不懂,實(shí)在不知道該怎么翻譯 > .. <)维贺。
正如這個(gè)例子它掂,下面的代碼實(shí)際上是會(huì)可以編譯的,雖然有人認(rèn)為可能不會(huì):
List l = new ArrayList();
Class c = l.getClass();
返回值
該對(duì)象類(lèi)的實(shí)例溯泣。
<sapn id="hashcode">public int hashCode()
</span>
返回一個(gè)該對(duì)象的 hash code虐秋,根據(jù)約定,如果兩個(gè)對(duì)象通過(guò) equals 方法返回 true垃沦,那么這兩個(gè)對(duì)象一定會(huì)返回相同的 hash code 值客给。這就意味著 Object 的所有子類(lèi)都會(huì)同時(shí)復(fù)寫(xiě)這兩個(gè)方法或是一個(gè)全都不復(fù)寫(xiě)。
注意栏尚,除非用 euqals 比較的信息改變起愈,否則 hash 的值是不會(huì)變的只恨。
如果想要實(shí)現(xiàn)自己的 hashCode 方法,參考寫(xiě)一個(gè)正確的 hashCode 方法.
返回值
該對(duì)象的 hash code抬虽。
參考
public final void notify()
由于一個(gè)正在等待該對(duì)象的監(jiān)聽(tīng)器的(通過(guò)調(diào)用 wait() 方法)線程被喚醒官觅。如果正在等待的線程多于一個(gè),VM 會(huì)任意選擇它們中的一個(gè)阐污。被選擇的這個(gè)線程不會(huì)馬上執(zhí)行休涤。該線程調(diào)用 notify() 方法先釋放該對(duì)象的監(jiān)聽(tīng)器。而且笛辟,所選的線程仍要與試圖同步在同一對(duì)象上的其他線程競(jìng)爭(zhēng)功氨。
這個(gè)方法只能由該對(duì)象監(jiān)聽(tīng)器的線程調(diào)用。線程成為該對(duì)象監(jiān)聽(tīng)器的所有者
- 通過(guò)執(zhí)行該對(duì)象的同步方法手幢;
- 通過(guò)執(zhí)行同步對(duì)象的同步語(yǔ)句的正文捷凄;
- 如果對(duì)象類(lèi)型為Class,則通過(guò)執(zhí)行同步靜態(tài)方法围来。
參考
notify()
wait()
wait(long)
wait(long,int)
Thread
public final void notifyAll()
由于所有正在等待該對(duì)象的監(jiān)聽(tīng)器的(通過(guò)調(diào)用 wait() 方法)線程被喚醒跺涤。這些線程不會(huì)馬上執(zhí)行。線程調(diào)用 notify() 方法先釋放該對(duì)象的監(jiān)聽(tīng)器监透。而且桶错,這些線程仍要與試圖同步在同一對(duì)象上的其他線程競(jìng)爭(zhēng)。
這個(gè)方法只能由該對(duì)象監(jiān)聽(tīng)器的線程調(diào)用胀蛮。線程成為該對(duì)象監(jiān)聽(tīng)器的所有者
- 通過(guò)執(zhí)行該對(duì)象的同步方法院刁;
- 通過(guò)執(zhí)行同步對(duì)象的同步語(yǔ)句的正文;
- 如果對(duì)象類(lèi)型為Class粪狼,則通過(guò)執(zhí)行同步靜態(tài)方法退腥。
異常
IllegalMonitorStateException(非法監(jiān)視狀態(tài)異常) 當(dāng)調(diào)用該方法的線程不是該對(duì)象監(jiān)聽(tīng)器的所有者。
參考
notify()
wait()
wait(long)
wait(long,int)
public String toString()
返回一個(gè)簡(jiǎn)潔的鸳玩,人類(lèi)可讀的描述該對(duì)象的字符串阅虫。建議子類(lèi)復(fù)寫(xiě)這個(gè)方法,并且提供一個(gè)考慮到該對(duì)象的類(lèi)型和數(shù)據(jù)的實(shí)現(xiàn)不跟。默認(rèn)的實(shí)現(xiàn)相當(dāng)于以下的表達(dá)形式:
getClass().getName() + '@' + Integer.toHexString(hashCode())
如果想要實(shí)現(xiàn)一個(gè)自己的 toString 方法颓帝,參見(jiàn)寫(xiě)一個(gè)正確的 toString 方法。
返回值
該對(duì)象的一個(gè)可打印的表達(dá)形式窝革。
public final void wait()
由于調(diào)用線程時(shí)要等到另一個(gè)線程調(diào)用了該對(duì)象的 notify() 或 notifyAll() 方法购城。該方法只能由該對(duì)象的監(jiān)聽(tīng)器的線程調(diào)用,參見(jiàn) notify() 中如何使一個(gè)線程成為監(jiān)聽(tīng)器的所有者虐译。
一個(gè)正在等待的線程可能會(huì)由于接受到 interrupt() 而導(dǎo)致提前停止等待瘪板,所以 wait 方法應(yīng)該循環(huán)調(diào)用,以檢查在繼續(xù)之前已經(jīng)等待的條件是否已滿足漆诽。
當(dāng)線程在等待的時(shí)候侮攀,它會(huì)放棄對(duì)該對(duì)象的監(jiān)聽(tīng)器的所有權(quán)锣枝。當(dāng)它被通知(或是被中斷)時(shí),在開(kāi)始運(yùn)行之前它會(huì)重新獲得監(jiān)聽(tīng)器兰英。
異常
IlleaglMonitorStateException (非法監(jiān)視狀態(tài)異常) 當(dāng)調(diào)用該方法的線程不是該對(duì)象的監(jiān)聽(tīng)所有者撇叁。
InterruptedException (中斷異常) 如果當(dāng)前線程已經(jīng)被中斷。在異常拋出之前畦贸,當(dāng)前線程的中斷狀態(tài)會(huì)被清除陨闹。
參考
notify()
notifyAll()
wait(long)
wait(long,int)
Thread
public final void wait(long millis,int nanos)
由于調(diào)用線程時(shí)要等到另一個(gè)線程調(diào)用了該對(duì)象的 notify() 或 notifyAll() 方法,或是過(guò)了指定的超時(shí)時(shí)間薄坏。該方法只由該對(duì)象的監(jiān)聽(tīng)器的線程調(diào)用趋厉,參見(jiàn) notify() 中如何使一個(gè)線程成為監(jiān)聽(tīng)器的所有者。
一個(gè)正在等待的線程可能會(huì)由于接受到 interrupt() 而導(dǎo)致提前停止等待胶坠,所以 wait 方法應(yīng)該循環(huán)調(diào)用君账,以檢查在繼續(xù)之前已經(jīng)等待的條件是否已滿足。
當(dāng)線程在等待的時(shí)候沈善,它會(huì)放棄對(duì)該對(duì)象的監(jiān)聽(tīng)器的所有權(quán)杈绸。當(dāng)它被通知(或是被中斷)時(shí),在開(kāi)始運(yùn)行之前它會(huì)重新獲得監(jiān)聽(tīng)器矮瘟。
當(dāng)超時(shí)時(shí)間為 0 時(shí),表示正在調(diào)用的線程應(yīng)該一直等待塑娇,除非被中斷或是被通知澈侠。
參數(shù)
millis 等待的最大時(shí)間,以毫秒為單位埋酬。
nanos 等待的毫秒數(shù)哨啃,以納少為單位。
異常
IllegalArgumentException (非法參數(shù)異常) 當(dāng) millis < 0,nanos < 0 或 nanos > 999999.
IllegalMonitorStateException (非法監(jiān)視狀態(tài)異常) 當(dāng)調(diào)用該方法的線程不是該對(duì)象的監(jiān)聽(tīng)所有者写妥。
InterruptedException (中斷異常) 如果當(dāng)前線程已經(jīng)被中斷拳球。在異常拋出之前,當(dāng)前線程的中斷狀態(tài)會(huì)被清除珍特。
參考
notify()
notifyAll()
wait(long)
wait(long,int)
Thread
public final void wait(long millis)
由于調(diào)用線程時(shí)要等到另一個(gè)線程調(diào)用了該對(duì)象的 notify() 或 notifyAll() 方法祝峻,或是過(guò)了指定的超時(shí)時(shí)間。該方法只由該對(duì)象的監(jiān)聽(tīng)器的線程調(diào)用扎筒,參見(jiàn) notify() 中如何使一個(gè)線程成為監(jiān)聽(tīng)器的所有者莱找。
一個(gè)正在等待的線程可能會(huì)由于接受到 interrupt() 而導(dǎo)致提前停止等待,所以 wait 方法應(yīng)該循環(huán)調(diào)用嗜桌,以檢查在繼續(xù)之前已經(jīng)等待的條件是否已滿足奥溺。
當(dāng)線程在等待的時(shí)候,它會(huì)放棄對(duì)該對(duì)象的監(jiān)聽(tīng)器的所有權(quán)骨宠。當(dāng)它被通知(或是被中斷)時(shí)浮定,在開(kāi)始運(yùn)行之前它會(huì)重新獲得監(jiān)聽(tīng)器相满。
當(dāng)超時(shí)時(shí)間為 0 時(shí),表示正在調(diào)用的線程應(yīng)該一直等待桦卒,除非被中斷或是被通知立美。
參數(shù)
millis 等待的最大時(shí)間,以毫秒為單位闸盔。
異常
IllegalArgumentException (非法參數(shù)異常) 當(dāng) millis < 0,nanos < 0 或 nanos > 999999.
IllegalMonitorStateException (非法監(jiān)視狀態(tài)異常) 當(dāng)調(diào)用該方法的線程不是該對(duì)象的監(jiān)聽(tīng)所有者悯辙。
InterruptedException (中斷異常) 如果當(dāng)前線程已經(jīng)被中斷。在異常拋出之前迎吵,當(dāng)前線程的中斷狀態(tài)會(huì)被清除躲撰。
參考
notify()
notifyAll()
wait(long)
wait(long,int)
Thread
Protected Methods(被保護(hù)的方法)
protected Object clone()
創(chuàng)造并返回該對(duì)象的一個(gè)副本。默認(rèn)的實(shí)現(xiàn)返回一個(gè)所謂的淺的("shallow")的副本:它創(chuàng)建一個(gè)同類(lèi)的新的實(shí)例击费,然后從該實(shí)例復(fù)制字段值(包括對(duì)象的引用)到新的實(shí)例拢蛋。相反,“深”副本(deep)還會(huì)遞歸地克隆嵌套對(duì)象蔫巩。需要實(shí)現(xiàn)這種克隆的子類(lèi)應(yīng)該調(diào)用 super.clone()來(lái)創(chuàng)建新的實(shí)例谆棱,然后創(chuàng)建嵌套的可變對(duì)象的深層副本。
返回值
該對(duì)象的副本圆仔。
異常
CloneNotSupportedException (克隆不支持異常) 如果該對(duì)象的類(lèi)不能實(shí)現(xiàn) Cloneable 接口垃瞧。
protected void finalize()
當(dāng)垃圾收集器檢測(cè)到該實(shí)例不再是可獲得的時(shí)調(diào)用。默認(rèn)不做任何操作坪郭,但為了釋放資源該方法可以被復(fù)寫(xiě)个从。
注意,重寫(xiě)該方法的對(duì)象比不重寫(xiě)更消耗資源歪沃。當(dāng)該對(duì)象是不可獲得的之后的終結(jié)器可能還會(huì)運(yùn)行一段時(shí)間嗦锐,這個(gè)由內(nèi)存的壓力決定,所以通過(guò)它們進(jìn)行清理不是好的做法沪曙。另外奕污,終結(jié)器運(yùn)行在單個(gè)VM范圍的終結(jié)器線程上,因此在終結(jié)器中時(shí)行模塊化工作不是好的做法液走。終結(jié)器通常只需要有一個(gè)類(lèi)碳默,那個(gè)類(lèi)有一個(gè)本地對(duì)等全,并且需要調(diào)用一個(gè)本地的方法去銷(xiāo)毀本地對(duì)等體缘眶。即便這樣腻窒,提供一個(gè)明確的關(guān)閉方法(并實(shí)現(xiàn) Closeable 接口)是好的做法,并且堅(jiān)持通過(guò)手動(dòng)調(diào)用處理實(shí)例磅崭。這對(duì)于像文件這樣的東西效果很好儿子,但對(duì)于像 BigInteger 這樣的東西來(lái)說(shuō),不是很好砸喻,那些典型的調(diào)用代碼必須處理大量的臨時(shí)文件柔逼。不幸的是蒋譬,從單個(gè)終結(jié)器線程的角度來(lái)看,創(chuàng)建大量臨時(shí)文件的代碼是最差的代碼愉适。
如果必須使用終結(jié)器犯助,要考慮至少提供一個(gè)自己的 ReferenceQueue 并且有自己的線程來(lái)處理這個(gè) queue。
與構(gòu)造函數(shù)不一樣维咸,終結(jié)器沒(méi)有自動(dòng)鏈接剂买。需要自己調(diào)用 super.finalize()。
由終結(jié)器拋出的未捕獲的異常被忽略癌蓖,不終止終結(jié)器的線程瞬哼。參考 Effective Java 第 7 條,有更詳細(xì)的說(shuō)明租副。
異常
Throwable