Java:Object类的基本原理未被声明为abstract
为什么java.lang.Object
类声明为抽象?
当然,对于一个有用的Object,它需要添加状态或行为,Object类是一个抽象,因此它应该被声明为abstract … 为什么他们选择不这样做?
安德,我认为你正在接近这个 – 不是意图 – 不必要的抽象程度。 我认为这个(恕我直言)不必要的抽象层次是造成这里“问题”的原因。 您可能正在从数学理论方法中接近这一点,我们中的许多人正在从“试图解决问题的程序员”方法中接近这一点。 我认为这种方法的不同导致了分歧。
当程序员看实用性以及如何实际实现某些东西时,有很多次你需要一些完全任意的Object,其实际的实例是完全不相关的。 它不能为空。 我在另一篇文章的评论中给出的示例是*Set
( *
== Hash
或Concurrent
或选择类型)的实现,这通常通过使用支持*Map
并使用Map
键作为Set来完成。 您通常不能使用null
作为Map
值,因此通常要做的是使用静态Object
实例作为值,该值将被忽略并且从不使用。 但是,需要一些非null占位符。
另一个常见的用途是使用synchronized
关键字,其中需要一些 Object
来进行同步,并且您希望确保您的同步项完全是私有的,以避免在不同的类无意中在同一个锁上同步时出现死锁。 一个非常常见的习惯用法是将一个private final Object
分配给一个类用作锁。 公平地说,从Java 5和java.util.concurrent.locks.Lock
以及相关的附加内容来看,这个习惯用法显然不太适用。
从历史上看,在Java Object
可实例化非常有用。 您可以提出一个很好的观点,即如果设计变化很小或API变化较小,则不再需要这样做。 你可能在这方面是正确的。
是的,API可以提供一个Placeholder
类来扩展Object
而不添加任何东西,以用作上述目的的占位符。 但是 – 如果你扩展Object
而不添加任何内容,除了允许Object
是抽象的之外,类中的值是什么? 数学上,理论上,也许人们可以找到一个价值,但实际上,它会增加什么价值呢?
编程中有些时候你需要一个对象, 一些对象, 任何非空的具体对象,你可以通过==
和/或.equals()
进行比较,但你不需要任何其他function。目的。 它仅作为唯一标识符存在,否则绝对没有任何作用。 Object
完美地满足了这个角色,并且(恕我直言)非常干净。
我猜这是为什么Object
没有被声明为抽象的部分原因:它直接对它有用。
即使Object
没有任何特定于它的状态或行为,它也很有用。
一个例子是它用作用于同步的通用防护:
public class Example { private final Object o = new Object(); public void doSomething() { synchronized (o) { // do possibly dangerous stuff } } }
虽然这个类在它的实现中有点简单(这里不明显为什么有一个显式对象是有用的,你可以只声明方法synchronized
)有几种情况,这是非常有用的。
Object是否指定扩展它的类必须实现的方法才能有用? 不,因此它不必是抽象的。
抽象类的概念具有明确定义的含义,不适用于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) { }
对象如何比null更令人反感?
它是一个很好的地方标记(无论如何都是空的)。
另外,我不认为如果没有需要继续使用的抽象方法来制作对象抽象是不好的设计。
我不是说零是自切片面包以来最好的东西 – 我前几天读了一篇文章“发明家”讨论了具有null概念的成本/价值…(我甚至认为null不是可想而知!我猜某个人可能声称他发明了零…)只是能够实例化Object并不比能够传递null更糟糕。
您永远不知道何时可能需要使用简单的Object作为占位符。 可以把它想象成在数值系统中具有零(并且null对此不起作用,因为null表示没有数据)。
应该有理由使一个类抽象化。 一种是防止客户端实例化类并强制它们仅使用子类(无论出于何种原因)。 另一种情况是,如果您希望通过提供抽象方法将其用作接口,则子类必须实现这些方法。 可能,设计人员Java没有看到这样的原因,所以java.lang.Object
仍然是具体的。
和往常一样,Guava来帮忙: http: //docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html这里的东西可以用来杀死nulls / Object实例代码中的“非空占位符”。
这里有完全分开的问题:
- 为什么他们没有让Object抽象?
- 如果他们决定在未来的版本中将其抽象出来,会发生多少灾难?