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

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

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中没有对象的构造函数是如何存在的? (如果是抽象类)

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

你不能实例化抽象类是真的吗?

是。

JVM是否在内部创建抽象类的对象?

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

JVM创建一个对象,该对象属于您创建的类(在您的情况下为ConcreteClass )。 它从超类( MyAbstractClass )和它的子类( ConcreteClass )获得的一个对象的方面,但只有一个对象。

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

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

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

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

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

以下是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创建对象,然后根据需要针对该对象运行尽可能多的构造函数(它们实际上应该被称为初始化器 ),以便为每个超类提供初始化对象部分的机会。

因此,在该代码中,会发生什么(并且您可以在调试器中逐步完成此操作以完全理解它):

  1. JVM创建一个对象

  2. 调用ConcreteClass构造函数

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

      1. 构造函数做的第一件事是调用它的超类的构造函数( Object的)

      2. Object构造函数返回时, MyAbstractClass构造函数的其余部分将运行

    2. MyAbtractClass构造函数返回时, ConcreteClass构造函数的其余部分将运行

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

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

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

JVM将创建一个对象,一个具体类的实例,它inheritance抽象类的字段和方法