JVM 是否在内部实例化抽象对象class?

Does the JVM internally instantiate an object for an abstract class?

我有一个抽象的class和它的具体子class,当我创建一个子class的对象时,它会自动调用超级构造函数。 JVM 是否在内部创建抽象对象 class?

public abstract class MyAbstractClass {

    public MyAbstractClass() {
        System.out.println("abstract default constructor");
    }

}
public class ConcreteClass extends MyAbstractClass{

    public static void main(String[] args) {
        new ConcreteClass();
    }

}

那么在 JVM 中构造函数如何在没有对象的情况下存在? (如果是摘要class)

构造函数在创建对象后执行,然后不创建抽象对象class默认构造函数如何执行?? (这个在Java Doc中有提到)

Is it true that you can't instantiate abstract class?

是的。

Is JVM internally create object of abstract class ?

不,但这是一个常见的误解(这并不是一种不合理的方式;像 JavaScript 这样的原型语言就是这样做的)。

JVM 创建一个 对象,它属于您创建的class(在您的例子中,ConcreteClass)。它从它的 superclass (MyAbstractClass) 和它的 subclass (ConcreteClass) 获得了一个对象的某些方面,但只有一个对象。

该对象是其所有部分的集合,包括似乎具有相同名称的部分,例如 superclass 的方法被 subclass 覆盖。事实上,这些方法具有不同的完全限定名称并且不会相互冲突,这就是为什么可以调用 superclass 版本的重写方法的原因。

所以如果它只是一个对象,为什么你会看到对 MyAbstractClass 的构造函数的调用?在我们回答这个问题之前,我需要提一下 Java 编译器正在做的一些您在源代码中看不到的事情:

  1. 它正在为 ConcreteClass 创建默认构造函数。

  2. 在该构造函数中,它正在调用 MyAbstractClass 构造函数。

  3. 只是为了彻底:在 MyAbstractClass 构造函数中,它添加了对 superclass 的 (Object) 构造函数的调用,因为没有super(...)MyAbstractClass 构造函数中编写的调用。

下面是 Java 编译器为您填充的位的代码:

public abstract class MyAbstractClass {

    public MyAbstractClass() {
        super();           // <== The Java compiler adds this call to Object's constructor (#3 in the list above)
        System.out.println("abstract default constructor");
    }

}
public class ConcreteClass extends MyAbstractClass{

    ConcreteClass() {      // <== The Java compiler adds this default constuctor (#1 in the list above)
        super();           // <== Which calls the superclass's (MyAbstractClass's) constructor (#2 in the list above)
    }

    public static void main(String[] args) {
        new ConcreteClass();
    }

}

好吧,撇开这个不谈,让我们谈谈评论中非常有用的一点 TheLostMind构造函数不 创建 对象,它们 初始化 它们 。 JVM 创建该对象,然后根据需要针对该对象运行尽可能多的构造函数(它们实际上应该称为 initializers),以便为每个 superclass 提供初始化 对象的部分

所以在该代码中,发生了什么(您可以在调试器中单步执行以完全理解它)是:

  1. JVM创建对象

  2. 调用了ConcreteClass构造函数

    1. 构造函数所做的第一件事是调用其超class的构造函数,在本例中为MyAbstractClass的构造函数. (请注意,这是绝对要求:Java 编译器不允许您在调用 superclass 构造函数之前在构造函数本身中包含任何逻辑。)

      1. 构造函数所做的第一件事是调用其超class的构造函数(Object的)

      2. Object构造函数returns时,MyAbstractClass构造函数的剩余部分运行

    2. MyAbtractClass构造函数returns时,ConcreteClass构造函数的剩余部分运行

  3. 对象作为 new ConcreteClass() 表达式的结果返回。

请注意,如果存在带有初始值设定项的实例字段,上述内容将变得更加复杂。有关完整详细信息,请参阅 JLS 和 JVM 规范。

JVM 不创建抽象对象 class。它正在调用它的超级构造函数

JVM 将创建一个对象,一个继承抽象class

字段和方法的具体实例class