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

Pur*_*jax 6 java constructor jvm default-constructor

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

我阅读了各种文章..有些人说编译器......还有其他人说JVM.我想非常肯定(证明会有很多帮助).

对不起,如果问题是愚蠢的(我还在消化术语)!

提前致谢.

Sim*_*lli 8

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

您不必为您的类提供任何构造函数,但在执行此操作时必须小心.编译器自动为没有构造函数的任何类提供无参数的默认构造函数.此默认构造函数将调用超类的无参数构造函数.在这种情况下,如果超类没有无参数构造函数,编译器将会抱怨,因此您必须验证它是否存在.如果你的类没有显式的超类,那么它有一个隐式的超类Object,它有一个无参数的构造函数.

  • 您应该考虑将重点放在“编译器”上,这可以回答问题。 (2认同)

Edw*_*rzo 5

对于正式引用,默认构造函数的性质在以下两个中解释:

或者,如果您使用的是Oracle JDK或OpenJDK,则可以轻松演示此行为,以验证编译器是否能够完成所有魔术.

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

你应该看到一个名为可执行javap$JDK_HOME/bin/

如果你有一个简单的文件Demo.java,例如只包含一个类,

public class Demo {}
Run Code Online (Sandbox Code Playgroud)

然后使用该命令编译它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
}
Run Code Online (Sandbox Code Playgroud)

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

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

public class Demo { 
  protected static class Other {}
}
Run Code Online (Sandbox Code Playgroud)

你编译它,然后做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
}
Run Code Online (Sandbox Code Playgroud)

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