简体   繁体   English

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

[英]Who provides the default constructor in Java? Compiler or JVM?

Is the constructor added at run-time or compile time?(I guess it is compile time). 构造函数是在运行时还是编译时添加的?(我想这是编译时)。 I need some in depth explanation please, at JVM architecture level. 在JVM架构级别,我需要一些深入的解释。

I read various articles.. some says compiler.. and others say JVM. 我阅读了各种文章..有些人说编译器......还有其他人说JVM。 I want to be very much sure(proofs will help a lot). 我想非常肯定(证明会有很多帮助)。

Sorry if the question is stupid(am still digesting the terminologies)!!! 对不起,如果问题是愚蠢的(我还在消化术语)!

Thanks in advance. 提前致谢。

From the Java Tutorial from Oracle: https://docs.oracle.com/javase/tutorial/java/javaOO/constructors.html 来自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. 如果你的类没有显式的超类,那么它有一个隐式的超类Object,它有一个无参数的构造函数。

For a formal reference, the nature of the default constructor is explained in both: 对于正式引用, 默认构造函数的性质在以下两个中解释:

Alternatively, if you're using Oracle JDK or OpenJDK, you could easily demonstrate this behavior to verify that it is the compiler the one that does all the magic. 或者,如果您使用的是Oracle JDK或OpenJDK,则可以轻松演示此行为,以验证编译器是否能够完成所有魔术。

All you need to do is to use the Java decompiler tool that comes with your JDK to see what bytecodes are being generated in your class files. 您需要做的就是使用JDK附带的Java反编译工具来查看类文件中生成的字节码。

You should see an executable named javap under $JDK_HOME/bin/ 您应该在$JDK_HOME/bin/下看到一个名为javap的可执行文件

If you had a simple file like Demo.java containing just one class, eg 如果您有一个像Demo.java这样的简单文件Demo.java包含一个类,例如

public class Demo {}

And you compile it using the command javac Demo.java , and then you run the decompiler using javap -c Demo , the output should say something like: 然后使用命令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
}

Which demonstrates that it is the compiler which adds the default constructor, since it was not in your source code but it is indeed in your compiled class file. 这表明它是添加默认构造函数的编译器,因为它不在您的源代码中,但它确实在您编译的类文件中。

You will also notice that the constructor access level matches that of the class for which it was generated. 您还会注意到构造函数访问级别与生成它的类的访问级别相匹配。 So, if you do 所以,如果你这样做

public class Demo { 
  protected static class Other {}
}

And you compile that, and then do a javap -c Demo.Other you get 你编译它,然后做一个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
}

Once more, demonstrating that the compiler adds a default constructor matching the accessibility of the class for which it was generated as the specifications above say it should do. 再一次,证明编译器添加了一个默认构造函数,该构造函数与生成它的类的可访问性相匹配,如上面的规范所说的那样。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM