繁体   English   中英

Java:Object类的基本原理未声明为抽象

[英]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* == HashConcurrent或选择类型)的实现,通常通过使用*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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM