Java中的默认构造函数是谁提供的?编译器还是 JVM?

Who provides the default constructor in Java? Compiler or JVM?

构造函数是在运行时添加的还是编译时添加的?(我猜是编译时)。 我需要一些深入的解释,在 JVM 架构级别。

我阅读了各种文章..一些说编译器..还有一些说 JVM。我想非常确定(证据会有很大帮助)。

抱歉,如果这个问题很愚蠢(我还在消化术语)!!!

提前致谢。

来自 Oracle 的 Java 教程:https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html

You don't have to provide any constructors for your class, but you must be careful when doing this. The compiler automatically provides a no-argument, default constructor for any class without constructors. This default constructor will call the no-argument constructor of the superclass. In this situation, the compiler will complain if the superclass doesn't have a no-argument constructor so you must verify that it does. If your class has no explicit superclass, then it has an implicit superclass of Object, which does have a no-argument constructor.

作为正式参考,默认构造函数的性质在以下两个方面都有解释:

或者,如果您使用的是 Oracle JDK 或 OpenJDK,您可以轻松地演示此行为以验证编译器是否是所有神奇的编译器。

您需要做的就是使用 JDK 附带的 Java 反编译器工具来查看 class 文件中生成的字节码。

您应该在 $JDK_HOME/bin/

下看到名为 javap 的可执行文件

如果您有一个像 Demo.java 这样只包含一个 class 的简单文件,例如

public class Demo {}

然后你使用命令 javac Demo.java 编译它,然后你 运行 使用 javap -c Demo 反编译器,输出应该是这样的:

Compiled from "Demo.java"
public class Demo {
  public Demo();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
}

这表明是编译器添加了默认构造函数,因为它不在您的源代码中,但确实在您编译的 class 文件中。

您还会注意到构造函数访问级别与生成它的 class 的访问级别相匹配。所以,如果你这样做

public class Demo { 
  protected static class Other {}
}

你编译它,然后做一个javap -c Demo.Other你得到

public class Demo$Other {
  protected Demo$Other();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return
}

再一次证明编译器添加了一个默认构造函数,该构造函数与 class 的可访问性相匹配,正如上面的规范所说的那样。