[英]Java: Rationale of the Object class not being declared abstract
為什么java.lang.Object
類沒有聲明為抽象的?
為了使Object有用,它肯定需要增加狀態或行為,Object類是一個抽象,因此應該將其聲明為abstract ... 為什么他們選擇不這樣做?
即使沒有特定的狀態或行為, Object
也很有用。
一個示例是將其用作用於同步的通用防護:
public class Example {
private final Object o = new Object();
public void doSomething() {
synchronized (o) {
// do possibly dangerous stuff
}
}
}
盡管此類的實現有點簡單(此處並不清楚為什么使用顯式對象很有用,但您可以將方法聲明為synchronized
),但在某些情況下,這確實很有用。
安德,我認為您正在以不必要的抽象程度接近此目標(雙關不是故意的)。 我認為這種(IMHO)不必要的抽象級別是造成此處“問題”的原因。 也許您是從數學理論方法來解決這個問題的,而我們中的許多人都是從“試圖解決問題的程序員”的方法解決這個問題的。 我認為這種方法上的差異導致了分歧。
當程序員着眼於實用性以及如何實際實現某些東西時,很多時候您需要某個完全與實際實例無關的任意對象。 它不能為空。 我在另一篇文章的評論中給出的示例是*Set
( *
== Hash
或Concurrent
或選擇類型)的實現,通常通過使用*Map
支持並將Map
鍵用作Set來實現。 您通常不能將null
用作Map
值,因此通常要做的是使用靜態Object
實例作為該值,該實例將被忽略並且從不使用。 但是,需要一些非空的占位符。
另一個常見的用法是與之synchronized
關鍵字,其中需要一些 Object
進行同步,並且您要確保您的同步項是完全私有的,以避免死鎖,因為不同的類在同一鎖上意外地進行了同步。 一個非常常見的習慣用法是分配一個private final Object
以在類中用作鎖。 公平地說,從Java 5和java.util.concurrent.locks.Lock
及相關附加功能開始,該慣用語不太適用。
從歷史上看,在Java Object
實例化是非常有用的。 您可能會指出,只要對設計進行較小的更改或對API進行較小的更改,就不再需要這樣做。 您可能是正確的。
是的,API可能已經提供了一個Placeholder
類,該類可以擴展Object
而不添加任何內容,而用作上述目的的占位符。 但是-如果要擴展Object
卻不添加任何內容,那么該類中的值除了允許Object
抽象之外,還有什么價值? 從數學上講,理論上也許可以找到一個價值,但在實用上,這樣做會增加什么價值呢?
有時在編程中需要一個對象, 某個對象, 任何不為null的具體對象,都可以通過==
和/或.equals()
進行比較,但是您不需要任何其他功能賓語。 它僅作為唯一標識符存在,否則絕對不起作用。 Object
完美地(IMHO)完全滿足此角色。
我想這就是為什么Object
不聲明為abstract的部分原因:不聲明它是直接有用的。
對象是否指定了擴展它的類必須實現的方法才能有用? 不,因此它不必是抽象的。
類是抽象的概念具有明確定義的含義,不適用於Object。
您可以為同步鎖實例化Object
:
Object lock = new Object();
void someMethod() {
//safe stuff
synchronized(lock) {
//some code avoiding race condition
}
}
void someOtherMethod() {
//safe code
synchronized(lock) {
//some other stuff avoiding race condition
}
}
我不確定這是原因,但是它允許(或允許,因為現在有更好的方法)將Object用作鎖:
Object lock = new Object();
....
synchronized(lock)
{
}
Object如何比null更具攻擊性?
它是一個很好的位置標記(無論如何都等於null)。
另外,我認為沒有一個需要繼續使用抽象方法的對象來抽象一個對象也不是一個好的設計。
我並不是說null是切成薄片的面包以來最好的東西-前幾天,我讀了“發明家”的一篇文章,討論了使用null概念的成本/價值...(我什至都不認為null是我猜想某處某人可能聲稱他發明了零..)只是能夠實例化Object並不比傳遞null差。
您永遠不知道何時要使用簡單的Object作為占位符。 可以將其視為在數字系統中為零(並且null對此不起作用,因為null表示缺少數據)。
應該有一個使類抽象化的理由。 一種是防止客戶端實例化該類,並迫使它們僅使用子類(無論出於何種原因)。 另一個是如果您想通過提供子類必須實現的抽象方法來將其用作接口。 也許Java的設計者沒有看到這樣的原因,所以java.lang.Object
仍然是具體的。
番石榴一如既往地為您提供幫助: http: //docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html此處的內容可用於殺死null /代碼中的“非空占位符”。
這里有完全分開的問題:
我會提出另一個原因,因為我發現Object可以自己實例化。 我有一個創建的對象池,其中包含多個插槽。 這些插槽可以包含許多對象中的任何一個,所有對象都從抽象類繼承。 但是我在池中放置什么來表示“空”。 我可以使用null
,但是出於我的目的,確保每個插槽中始終有一些對象才有意義。 我無法實例化放入其中的抽象類,而且我也不想這樣做。 因此,我可以為抽象類創建一個具體的子類來表示“不是有用的foo”,但是當使用Object的實例同樣好..實際上更好時,這似乎是不必要的,因為它清楚地說明了插槽中的內容沒有任何功能。 因此,在初始化池時,我通過創建一個對象來分配給每個插槽作為池的初始條件來進行初始化。
我同意,對於最初的Java工作人員來說,將Placeholder
對象定義為Object
的具體子類,然后將Object
抽象化可能是有意義的,但是這樣做並沒有給我任何錯。 然后,我將使用Placeholder
代替Object
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.