Object

Class Overview(類概述)

這個(gè)類是 Java 類等級(jí)中的根。所有非初級(jí)的類型(包括數(shù)組)都是直接或間接繼承這個(gè)類。

按照以下這種風(fēng)格寫一個(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ì)象的類型有誤,則返回 false
 // 這種類型可能是一個(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ù)念愋? // 這將是成功的因?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));
}

如果要重寫 equals 方法,同時(shí)也應(yīng)該重寫 hashCode 方法:相同的實(shí)例必須要有相同的哈希值。
參考 Effcetive Java 里的第 8 條,有更詳細(xì)的說(shuō)明。

按照以下這種風(fēng)格寫一人規(guī)范的 <span id="hash" >hashCode</span> 方法:

  @Override public int hashCode() {
 // Start with a non-zero constant.
 // 開始于一個(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;
 }

如果不打算將您的類型用作哈希鍵, 也不要只依賴于默認(rèn)的 hashCode 方法實(shí)現(xiàn)。因?yàn)檫@樣會(huì)不明顯的破壞將來(lái)任何一個(gè)把該類型做為哈希鍵的編碼。應(yīng)該用拋異常的方法來(lái)替代:

 @Override public int hashCode() {
 throw new UnsupportedOperationException();
}

參考 Effective Java 第 9 條,有更詳細(xì)的說(shuō)明。

為了調(diào)試方便,按照以下的風(fēng)格重寫 <span id="toString"> toString </span>是很常見的:

 @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)表示與此實(shí)例相同的對(duì)象。
通用約定是,這種比較應(yīng)該是自反性,對(duì)稱性,傳遞性。除了 null,沒(méi)有引用的對(duì)象等于 null。

僅僅當(dāng) this==o 的時(shí)候默認(rèn)返回 true。如果想要實(shí)現(xiàn)自己的 equals 方法,參考寫一個(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è)子類通常這兩個(gè)方法都會(huì)復(fù)寫,或者都不復(fù)寫。

參數(shù)

o 與該實(shí)例比較的對(duì)象。

返回值

如果指定的對(duì)象與該對(duì)象相同,返回 true ,否則返回 false。

參考

hashCode()

public final Class<?> getClass()

返回一個(gè)唯一的 Class 實(shí)例,表示這個(gè)對(duì)象的類。注意,getClass()是一個(gè)特例,它事實(shí)上返回Class ,Foo 是對(duì)表達(dá)式類型的擦除當(dāng) getClass()被調(diào)用時(shí)(這里我也不懂,實(shí)在不知道該怎么翻譯 > .. <)。

正如這個(gè)例子,下面的代碼實(shí)際上是會(huì)可以編譯的,雖然有人認(rèn)為可能不會(huì):

List l = new ArrayList();
Class c = l.getClass();

返回值

該對(duì)象類的實(shí)例。

<sapn id="hashcode">public int hashCode()</span>

返回一個(gè)該對(duì)象的 hash code,根據(jù)約定,如果兩個(gè)對(duì)象通過(guò) equals 方法返回 true,那么這兩個(gè)對(duì)象一定會(huì)返回相同的 hash code 值。這就意味著 Object 的所有子類都會(huì)同時(shí)復(fù)寫這兩個(gè)方法或是一個(gè)全都不復(fù)寫。

注意,除非用 euqals 比較的信息改變,否則 hash 的值是不會(huì)變的。

如果想要實(shí)現(xiàn)自己的 hashCode 方法,參考寫一個(gè)正確的 hashCode 方法.

返回值

該對(duì)象的 hash code。

參考

equals(Object)

public final void notify()

由于一個(gè)正在等待該對(duì)象的監(jiān)聽器的(通過(guò)調(diào)用 wait() 方法)線程被喚醒。如果正在等待的線程多于一個(gè),VM 會(huì)任意選擇它們中的一個(gè)。被選擇的這個(gè)線程不會(huì)馬上執(zhí)行。該線程調(diào)用 notify() 方法先釋放該對(duì)象的監(jiān)聽器。而且,所選的線程仍要與試圖同步在同一對(duì)象上的其他線程競(jìng)爭(zhēng)。

這個(gè)方法只能由該對(duì)象監(jiān)聽器的線程調(diào)用。線程成為該對(duì)象監(jiān)聽器的所有者

  • 通過(guò)執(zhí)行該對(duì)象的同步方法;
  • 通過(guò)執(zhí)行同步對(duì)象的同步語(yǔ)句的正文;
  • 如果對(duì)象類型為Class,則通過(guò)執(zhí)行同步靜態(tài)方法。

參考

notify()

wait()

wait(long)

wait(long,int)

Thread

public final void notifyAll()

由于所有正在等待該對(duì)象的監(jiān)聽器的(通過(guò)調(diào)用 wait() 方法)線程被喚醒。這些線程不會(huì)馬上執(zhí)行。線程調(diào)用 notify() 方法先釋放該對(duì)象的監(jiān)聽器。而且,這些線程仍要與試圖同步在同一對(duì)象上的其他線程競(jìng)爭(zhēng)。

這個(gè)方法只能由該對(duì)象監(jiān)聽器的線程調(diào)用。線程成為該對(duì)象監(jiān)聽器的所有者

  • 通過(guò)執(zhí)行該對(duì)象的同步方法;
  • 通過(guò)執(zhí)行同步對(duì)象的同步語(yǔ)句的正文;
  • 如果對(duì)象類型為Class,則通過(guò)執(zhí)行同步靜態(tài)方法。

異常

IllegalMonitorStateException(非法監(jiān)視狀態(tài)異常) 當(dāng)調(diào)用該方法的線程不是該對(duì)象監(jiān)聽器的所有者。

參考

notify()

wait()

wait(long)

wait(long,int)

public String toString()

返回一個(gè)簡(jiǎn)潔的,人類可讀的描述該對(duì)象的字符串。建議子類復(fù)寫這個(gè)方法,并且提供一個(gè)考慮到該對(duì)象的類型和數(shù)據(jù)的實(shí)現(xiàn)。默認(rèn)的實(shí)現(xiàn)相當(dāng)于以下的表達(dá)形式:

   getClass().getName() + '@' + Integer.toHexString(hashCode())

如果想要實(shí)現(xiàn)一個(gè)自己的 toString 方法,參見寫一個(gè)正確的 toString 方法。

返回值

該對(duì)象的一個(gè)可打印的表達(dá)形式。

public final void wait()

由于調(diào)用線程時(shí)要等到另一個(gè)線程調(diào)用了該對(duì)象的 notify() 或 notifyAll() 方法。該方法只能由該對(duì)象的監(jiān)聽器的線程調(diào)用,參見 notify() 中如何使一個(gè)線程成為監(jiān)聽器的所有者。

一個(gè)正在等待的線程可能會(huì)由于接受到 interrupt() 而導(dǎo)致提前停止等待,所以 wait 方法應(yīng)該循環(huán)調(diào)用,以檢查在繼續(xù)之前已經(jīng)等待的條件是否已滿足。

當(dāng)線程在等待的時(shí)候,它會(huì)放棄對(duì)該對(duì)象的監(jiān)聽器的所有權(quán)。當(dāng)它被通知(或是被中斷)時(shí),在開始運(yùn)行之前它會(huì)重新獲得監(jiān)聽器。

異常

IlleaglMonitorStateException (非法監(jiān)視狀態(tài)異常) 當(dāng)調(diào)用該方法的線程不是該對(duì)象的監(jiān)聽所有者。

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)聽器的線程調(diào)用,參見 notify() 中如何使一個(gè)線程成為監(jiān)聽器的所有者。

一個(gè)正在等待的線程可能會(huì)由于接受到 interrupt() 而導(dǎo)致提前停止等待,所以 wait 方法應(yīng)該循環(huán)調(diào)用,以檢查在繼續(xù)之前已經(jīng)等待的條件是否已滿足。

當(dāng)線程在等待的時(shí)候,它會(huì)放棄對(duì)該對(duì)象的監(jiān)聽器的所有權(quán)。當(dāng)它被通知(或是被中斷)時(shí),在開始運(yùn)行之前它會(huì)重新獲得監(jiān)聽器。

當(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)聽所有者。

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)聽器的線程調(diào)用,參見 notify() 中如何使一個(gè)線程成為監(jiān)聽器的所有者。

一個(gè)正在等待的線程可能會(huì)由于接受到 interrupt() 而導(dǎo)致提前停止等待,所以 wait 方法應(yīng)該循環(huán)調(diào)用,以檢查在繼續(xù)之前已經(jīng)等待的條件是否已滿足。

當(dāng)線程在等待的時(shí)候,它會(huì)放棄對(duì)該對(duì)象的監(jiān)聽器的所有權(quán)。當(dāng)它被通知(或是被中斷)時(shí),在開始運(yùn)行之前它會(huì)重新獲得監(jiān)聽器。

當(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)聽所有者。

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è)同類的新的實(shí)例,然后從該實(shí)例復(fù)制字段值(包括對(duì)象的引用)到新的實(shí)例。相反,“深”副本(deep)還會(huì)遞歸地克隆嵌套對(duì)象。需要實(shí)現(xiàn)這種克隆的子類應(yīng)該調(diào)用 super.clone()來(lái)創(chuàng)建新的實(shí)例,然后創(chuàng)建嵌套的可變對(duì)象的深層副本。

返回值

該對(duì)象的副本。

異常

CloneNotSupportedException (克隆不支持異常) 如果該對(duì)象的類不能實(shí)現(xiàn) Cloneable 接口。

protected void finalize()

當(dāng)垃圾收集器檢測(cè)到該實(shí)例不再是可獲得的時(shí)調(diào)用。默認(rèn)不做任何操作,但為了釋放資源該方法可以被復(fù)寫。

注意,重寫該方法的對(duì)象比不重寫更消耗資源。當(dāng)該對(duì)象是不可獲得的之后的終結(jié)器可能還會(huì)運(yùn)行一段時(shí)間,這個(gè)由內(nèi)存的壓力決定,所以通過(guò)它們進(jìn)行清理不是好的做法。另外,終結(jié)器運(yùn)行在單個(gè)VM范圍的終結(jié)器線程上,因此在終結(jié)器中時(shí)行模塊化工作不是好的做法。終結(jié)器通常只需要有一個(gè)類,那個(gè)類有一個(gè)本地對(duì)等全,并且需要調(diào)用一個(gè)本地的方法去銷毀本地對(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

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本文出自 Eddy Wiki ,轉(zhuǎn)載請(qǐng)注明出處:http://eddy.wiki/interview-java.h...
    eddy_wiki閱讀 2,298評(píng)論 0 14
  • Object類是Java中其他所有類的祖先,沒(méi)有Object類Java面向?qū)ο鬅o(wú)從談起。作為其他所有類的基類,Ob...
    時(shí)待吾閱讀 563評(píng)論 0 1
  • 做為旅行達(dá)人,花是沒(méi)少拍,但是從來(lái)也沒(méi)有寫過(guò)花…… 我知道各種花都有各種花的美,但具體是怎么個(gè)美法,我又有些“理屈...
    攝影旅行家閱讀 1,095評(píng)論 0 2
  • 這么長(zhǎng)的時(shí)間,我終于有了勇氣與自己對(duì)話,開始撕開傷疤正視血淋淋的傷口。 一個(gè)人獨(dú)自徘徊,一家清吧出現(xiàn)在眼前。或許是...
    糾結(jié)的MAN閱讀 293評(píng)論 0 0
  • 白駒過(guò)隙,轉(zhuǎn)眼間,時(shí)光就裹挾著我們來(lái)到11月。 寒風(fēng)乍起,黃葉飄零。 突兀的枝椏如一根根精血盡亡的手指,伸向遼遠(yuǎn)的...
    云小嬋閱讀 220評(píng)論 0 0

友情鏈接更多精彩內(nèi)容