简体   繁体   English

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

[英]Java: Rationale of the Object class not being declared abstract

Why wasn't the java.lang.Object class declared to be abstract ? 为什么java.lang.Object类没有声明为抽象的?

Surely for an Object to be useful it needs added state or behaviour, an Object class is an abstraction, and as such it should have been declared abstract ... why did they choose not to ? 为了使Object有用,它肯定需要增加状态或行为,Object类是一个抽象,因此应该将其声明为abstract ... 为什么他们选择不这样做?

An Object is useful even if it does not have any state or behaviour specific to it. 即使没有特定的状态或行为, Object也很有用。

One example would be its use as a generic guard that's used for synchronization: 一个示例是将其用作用于同步的通用防护:

public class Example {
    private final Object o = new Object();

    public void doSomething() {
        synchronized (o) {
            // do possibly dangerous stuff
        }
    }
}

While this class is a bit simple in its implementation (it isn't evident here why it's useful to have an explicit object, you could just declare the method synchronized ) there are several cases where this is really useful. 尽管此类的实现有点简单(此处并不清楚为什么使用显式对象很有用,但您可以将方法声明为synchronized ),但在某些情况下,这确实很有用。

Ande, I think you are approaching this -- pun NOT intended -- with an unnecessary degree of abstraction. 安德,我认为您正在以不必要的抽象程度接近此目标(双关不是故意的)。 I think this (IMHO) unnecessary level of abstraction is what is causing the "problem" here. 我认为这种(IMHO)不必要的抽象级别是造成此处“问题”的原因。 You are perhaps approaching this from a mathematical theoretical approach, where many of us are approaching this from a "programmer trying to solve problems" approach. 也许您是从数学理论方法来解决这个问题的,而我们中的许多人都是从“试图解决问题的程序员”的方法解决这个问题的。 I believe this difference in approach is causing the disagreements. 我认为这种方法上的差异导致了分歧。

When programmers look at practicalities and how to actually implement something, there are a number of times when you need some totally arbitrary Object whose actual instance is totally irrelevant. 当程序员着眼于实用性以及如何实际实现某些东西时,很多时候您需要某个完全与实际实例无关的任意对象。 It just cannot be null. 它不能为空。 The example I gave in a comment to another post is the implementation of *Set ( * == Hash or Concurrent or type of choice), which is commonly done by using a backing *Map and using the Map keys as the Set. 我在另一篇文章的评论中给出的示例是*Set* == HashConcurrent或选择类型)的实现,通常通过使用*Map支持并将Map键用作Set来实现。 You often cannot use null as the Map value, so what is commonly done is to use a static Object instance as the value, which will be ignored and never used. 您通常不能将null用作Map值,因此通常要做的是使用静态Object实例作为该值,该实例将被忽略并且从不使用。 However, some non-null placeholder is needed. 但是,需要一些非空的占位符。

Another common use is with the synchronized keyword where some Object is needed to synchronize on, and you want to ensure that your synchronizing item is totally private to avoid deadlock where different classes are unintentionally synchronizing on the same lock. 另一个常见的用法是与之synchronized关键字,其中需要一些 Object进行同步,并且您要确保您的同步项是完全私有的,以避免死锁,因为不同的类在同一锁上意外地进行了同步。 A very common idiom is to allocate a private final Object to use in a class as the lock. 一个非常常见的习惯用法是分配一个private final Object以在类中用作锁。 To be fair, as of Java 5 and java.util.concurrent.locks.Lock and related additions, this idiom is measurably less applicable. 公平地说,从Java 5和java.util.concurrent.locks.Lock及相关附加功能开始,该惯用语不太适用。

Historically, it has been quite useful in Java to have Object be instantiable. 从历史上看,在Java Object实例化是非常有用的。 You could make a good point that with small changes in design or with small API changes, this would no longer be necessary. 您可能会指出,只要对设计进行较小的更改或对API进行较小的更改,就不再需要这样做。 You're probably correct in this. 您可能是正确的。

And yes, the API could have provided a Placeholder class that extends Object without adding anything at all, to be used as a placeholder for the purposes described above. 是的,API可能已经提供了一个Placeholder类,该类可以扩展Object而不添加任何内容,而用作上述目的的占位符。 But -- if you're extending Object but adding nothing, what is the value in the class other than allowing Object to be abstract? 但是-如果要扩展Object却不添加任何内容,那么该类中的值除了允许Object抽象之外,还有什么价值? Mathematically, theoretically, perhaps one could find a value, but pragmatically, what value would it add to do this? 从数学上讲,理论上也许可以找到一个价值,但在实用上,这样做会增加什么价值呢?

There are times in programming where you need an object, some object, any concrete object that is not null, something that you can compare via == and/or .equals() , but you just don't need any other feature to this object. 有时在编程中需要一个对象, 某个对象, 任何不为null的具体对象,都可以通过==和/或.equals()进行比较,但是您不需要任何其他功能宾语。 It exists only to serve as a unique identifier and otherwise does absolutely nothing. 它仅作为唯一标识符存在,否则绝对不起作用。 Object satisfies this role perfectly and (IMHO) very cleanly. Object完美地(IMHO)完全满足此角色。

I would guess that this is part of the reason why Object was not declared abstract: It is directly useful for it not to be. 我想就是为什么Object不声明为abstract的部分原因:不声明它是直接有用的。

Does Object specify methods that classes extending it must implement in order to be useful? 对象是否指定了扩展它的类必须实现的方法才能有用? No, and therefor it needn't be abstract. 不,因此它不必是抽象的。

The concept of a class being abstract has a well defined meaning that does not apply to Object. 类是抽象的概念具有明确定义的含义,不适用于Object。

You can instantiate Object for synchronization locks: 您可以为同步锁实例化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
  }
}

I am not sure this is the reason, but it allows (or allowed, as there are now better ways of doing it) for an Object to be used as a lock: 我不确定这是原因,但是它允许(或允许,因为现在有更好的方法)将Object用作锁:

Object lock = new Object();

....


synchronized(lock)
{
}

How is Object any more offensive than null? Object如何比null更具攻击性?

It makes a good place marker (as good as null anyway). 它是一个很好的位置标记(无论如何都等于null)。

Also, I don't think it would be good design to make an object abstract without an abstract method that needs to go on it. 另外,我认为没有一个需要继续使用抽象方法的对象来抽象一个对象也不是一个好的设计。

I'm not saying null is the best thing since sliced bread--I read an article the other day by the "Inventor" discussing the cost/value of having the concept of null... (I didn't even think null was inventable! I guess someone somewhere could claim he invented zero..) just that being able to instantiate Object is no worse than being able to pass null. 我并不是说null是切成薄片的面包以来最好的东西-前几天,我读了“发明家”的一篇文章,讨论了使用null概念的成本/价值...(我什至都​​不认为null是我猜想某处某人可能声称他发明了零..)只是能够实例化Object并不比传递null差。

You never know when you might want to use a simple Object as a placeholder. 您永远不知道何时要使用简单的Object作为占位符。 Think of it as like having a zero in a numerical system (and null doesn't work for this, since null represents the absence of data). 可以将其视为在数字系统中为零(并且null对此不起作用,因为null表示缺少数据)。

There should be a reason to make a class abstract. 应该有一个使类抽象化的理由。 One is to prevent clients from instantiating the class and force them into using only subclasses (for whatever reasons). 一种是防止客户端实例化该类,并迫使它们仅使用子类(无论出于何种原因)。 Another is if you wish to use it as an interface by providing abstract methods, which subclasses must implement. 另一个是如果您想通过提供子类必须实现的抽象方法来将其用作接口。 Probably, the designers og Java saw no such reasons, so java.lang.Object remains concrete. 也许Java的设计者没有看到这样的原因,所以java.lang.Object仍然是具体的。

As always, Guava comes to help: with http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html Stuff here can be used to kill nulls / Object instances for "a not-null placeholder" from the code. 番石榴一如既往地为您提供帮助: http: //docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/base/Optional.html此处的内容可用于杀死null /代码中的“非空占位符”。

There are entirely seperated questions here: 这里有完全分开的问题:

  • why did not they make Object abstract? 他们为什么不使对象抽象化?
  • how much disaster comes after if they decide to make it abstract in a future release? 如果他们决定在将来的版本中抽象出来,将会带来多少灾难?

I'll just throw in another reason that I've found Object to useful to instantiate on its own. 我会提出另一个原因,因为我发现Object可以自己实例化。 I have a pool of objects I've created that has a number of slots. 我有一个创建的对象池,其中包含多个插槽。 Those slots can contain any of a number of objects, all that inherit from an abstract class. 这些插槽可以包含许多对象中的任何一个,所有对象都从抽象类继承。 But what do I put in the pool to represent "empty". 但是我在池中放置什么来表示“空”。 I could use null , but for my purpose, it made more sense to insure that there was always some object in each slot. 我可以使用null ,但是出于我的目的,确保每个插槽中始终有一些对象才有意义。 I can't instantiate the abstract class to put in there, and I wouldn't have wanted to. 我无法实例化放入其中的抽象类,而且我也不想这样做。 So I could have created a concrete subclass of my abstract class to represent "not a useful foo", but that seemed unnecessary when using an instance of Object was just as good..in fact better, as it clearly says that what's in the slot has no functionality. 因此,我可以为抽象类创建一个具体的子类来表示“不是有用的foo”,但是当使用Object的实例同样好..实际上更好时,这似乎是不必要的,因为它清楚地说明了插槽中的内容没有任何功能。 So when I initialize my pool, I do so by creating an Object to assign to each slot as the initial condition of the pool. 因此,在初始化池时,我通过创建一个对象来分配给每个插槽作为池的初始条件来进行初始化。

I agree that it might have made sense for the original Java crew to have defined a Placeholder object as a concrete subclass of Object , and then made Object abstract, but it doesn't rub me wrong at all that they went the way they did. 我同意,对于最初的Java工作人员来说,将Placeholder对象定义为Object的具体子类,然后将Object抽象化可能是有意义的,但是这样做并没有给我任何错。 I would then have used Placeholder in place of Object . 然后,我将使用Placeholder代替Object

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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