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 编译器正在做的一些您在源代码中看不到的事情:
它正在为 ConcreteClass
创建默认构造函数。
在该构造函数中,它正在调用 MyAbstractClass
构造函数。
只是为了彻底:在 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 提供初始化 对象的部分。
所以在该代码中,发生了什么(您可以在调试器中单步执行以完全理解它)是:
JVM创建对象
调用了ConcreteClass
构造函数
构造函数所做的第一件事是调用其超class的构造函数,在本例中为MyAbstractClass
的构造函数. (请注意,这是绝对要求:Java 编译器不允许您在调用 superclass 构造函数之前在构造函数本身中包含任何逻辑。)
构造函数所做的第一件事是调用其超class的构造函数(Object
的)
当Object
构造函数returns时,MyAbstractClass
构造函数的剩余部分运行
当MyAbtractClass
构造函数returns时,ConcreteClass
构造函数的剩余部分运行
对象作为 new ConcreteClass()
表达式的结果返回。
请注意,如果存在带有初始值设定项的实例字段,上述内容将变得更加复杂。有关完整详细信息,请参阅 JLS 和 JVM 规范。
JVM 不创建抽象对象 class。它正在调用它的超级构造函数
JVM 将创建一个对象,一个继承抽象class
字段和方法的具体实例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 编译器正在做的一些您在源代码中看不到的事情:
它正在为
ConcreteClass
创建默认构造函数。在该构造函数中,它正在调用
MyAbstractClass
构造函数。只是为了彻底:在
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 提供初始化 对象的部分。
所以在该代码中,发生了什么(您可以在调试器中单步执行以完全理解它)是:
JVM创建对象
调用了
ConcreteClass
构造函数构造函数所做的第一件事是调用其超class的构造函数,在本例中为
MyAbstractClass
的构造函数. (请注意,这是绝对要求:Java 编译器不允许您在调用 superclass 构造函数之前在构造函数本身中包含任何逻辑。)构造函数所做的第一件事是调用其超class的构造函数(
Object
的)当
Object
构造函数returns时,MyAbstractClass
构造函数的剩余部分运行
当
MyAbtractClass
构造函数returns时,ConcreteClass
构造函数的剩余部分运行
对象作为
new ConcreteClass()
表达式的结果返回。
请注意,如果存在带有初始值设定项的实例字段,上述内容将变得更加复杂。有关完整详细信息,请参阅 JLS 和 JVM 规范。
JVM 不创建抽象对象 class。它正在调用它的超级构造函数
JVM 将创建一个对象,一个继承抽象class
字段和方法的具体实例class