什么负责生成默认构造函数?
如果每个类都有一个默认构造函数,那么谁生成它,编译器还是 JVM?
回答
简短的回答是,如有必要,编译器将生成一个默认构造函数。
绝对是 Java 到字节码编译器。您可以通过.class使用javap. 您应该会看到已插入的构造函数。
不过我也想纠正这个可能的误解:
如果每个类都有一个默认构造函数......
事实上,每个类都没有默认构造函数。
一个默认的构造函数只注入类,如果该类没有宣布任何构造。如果源代码根本没有声明任何构造函数,则不会注入默认构造函数。例如:
/* This has a no-args constructor, but it is not a "default" constructor */
public class Foo {
public Foo() {}
}
/* This has no no-args constructor and no "default" constructor */
public class Bar {
public Bar(int arg) {}
}
/* This has a "default" constructor */
public class Baz {
}
(默认构造函数是无参数构造函数,但显式声明的无参数构造函数不是默认构造函数。而且并非所有类都有无参数构造函数。)
(在 JVM 级别,要求.class文件至少定义一个构造函数。但是,对构造函数的参数数量和类型或构造函数的访问修饰符没有特定约束。)
另一个答案包括建议明确声明无参数构造函数,而不是依赖 Java 来插入默认构造函数(见上文)。
我认为这是个坏主意:
-
它对运行时性能的影响为零。
-
它对编译时间的影响最小1。事实上,它甚至可能使编译速度变慢。
- 如果没有构造函数,编译器会注意到这一点,并注入代码并生成默认构造函数。
- 如果存在显式(空)无参数构造函数,编译器必须读取、解析和类型检查构造函数,然后代码生成与第一种情况相同的构造函数。
-
可读性优势值得怀疑。
选择显式无参数构造函数而不是默认构造函数的唯一 (IMO)合理理由是:
- 因为还有其他构造函数(这意味着不会有默认的无参数构造函数!),
- 因为你想限制构造函数的可见性;例如
private在单例类中声明它,或 - 因为您想在 javadocs 中为 no-args 构造函数说点什么(有意义的)。
1 - 我的猜测将少于 1 毫秒。太小了,无法产生明显的差异。