当前位置: 首页 > 知识库问答 >
问题:

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

高迪
2023-03-14

我有一个抽象类及其具体子类,当我创建子类的对象时,它会自动调用超级构造函数。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文档中有所提及)

共有3个答案

姚鹤龄
2023-03-14

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

苏宾鸿
2023-03-14

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

仲孙逸明
2023-03-14

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

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

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

JVM创建一个对象,该对象属于您创建的类(在您的例子中,ConcreteClass)。它从超类(<code>MyAbstractClass</code>)和子类(<code>ConcreteClass</code>)中获得了一个对象的一些方面,但只有一个对象。

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

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

>

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

    在该构造函数中,它调用MyAbstractclass构造函数。

    为了彻底起见:在< code>MyAbstractClass构造函数中,它添加了对超类(< code>Object)构造函数的调用,因为没有< code>super(...)在< code>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创建对象,然后根据需要对一个对象运行尽可能多的构造函数(它们实际上应该被称为初始值设定项),以便给每个超类一个初始化其对象部分的机会。

    因此,在这段代码中,发生的事情(您可以在调试器中一步一步地完成,以完全理解它)是:

    > < Li > < p > JVM创建对象

    调用< code>ConcreteClass构造函数

    > < li>

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

    >

  • 构造函数所做的第一件事是调用其超类的构造函数(Object的)

    当<code>Object</code>构造函数返回时,<code>MyAbstractClass</ccode>构造函数的其余部分将运行

    MyAbtractclass构造函数返回时,Concreteclass构造函数的其余部分运行

    该对象作为< code>new ConcreteClass()表达式的结果返回。

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

  •  类似资料:
    • 我查过了,发现最接近的是这个,除了我没有任何向前的声明。我在基类中只有一个纯虚函数,我在子类中实现它,如下所示: 命令H 命令cpp 数字H 数字cpp 发生文件错误: 一个dd.cpp 添加H

    • 当我创建一个抽象类的对象时,我必须像接口一样这样做。 这是否意味着的对象是匿名的内部类对象?

    • 所以我有两个类。一个只有纯粹的虚拟函数。另一个实现了这些函数,并从第一个类派生出来。我知道我不能实例化第一个类。但是当我试图创建第二个类的对象时,它也失败了。 我的第二节课大体上是这样的: 执行: 下面是我如何实例化它并得到错误: 我哪里做错了? 第一课

    • 问题内容: 我创建了一个空的抽象类,并从中继承了该类: 我期望输出是 但是,我得到的是 如果我删除(这样就变成一个普通的类)和/或如果我设置了其他值,问题(显然)就消失了。 这里发生了什么? 问题答案: 这实际上不是ABC的问题,而是PyMongo的问题。有一个关于它的问题在这里。似乎pymongo重写以返回某种数据库类。这意味着将返回一个数据库对象,该对象在布尔上下文中为true。这使ABCMe

    • 问题内容: 我在查看OOP类文档时发现了以下示例: 我发现它们从同一类的主体实例化一个对象令人困惑。这被认为是不良做法吗?新创建的对象会具有main方法吗? 谢谢! 问题答案: 这根本没有错。这是完全正常的。(诚​​然,将具有main方法的类显然可以 执行的 事情更有意义- 类中的方法没有太大意义。) 对象实际上没有方法- 类 具有方法,或者是静态方法(在没有任何特定上下文的情况下调用),而实例方

    • 我正在学习OOP的概念。在阅读继承的过程中,我了解到在初始化子类之前必须先初始化超类,即所有超类的构造函数必须在子类构造函数之前运行。此外,我们还可以直接创建超级类的实例。对于例如。 现在,我遇到了抽象类。看来我们不能实例化一个抽象类。要使用抽象类,您必须从另一个类继承它,并为其中的抽象方法提供实现。 我的问题是,在实例化具体子类的同时,抽象超类的构造函数会在具体子类的构造函数之前被调用。如果是这