gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-01 21:46:05 25 4
gpt4 key购买 nike

我有一个抽象类和它的具体子类,当我创建子类的对象时它会自动调用 super 构造函数。 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 中提到)

最佳答案

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

是的。

Is JVM internally create object of abstract class ?

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

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

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

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

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

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

  3. 为了彻底:在 MyAbstractClass 构造函数中,它添加了对父类(super class)的 (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 创建对象,然后根据需要针对该对象运行尽可能多的构造函数(它们实际上应该称为初始化器),以便为每个父类(super class)提供初始化它的部分的机会对象的。

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

  1. JVM 创建一个对象

  2. ConcreteClass构造函数被调用

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

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

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

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

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

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

关于java - JVM 是否在内部实例化抽象类的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30125552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com