我有一个包含私有类的公共类:
public class A {
private class B
{
}
private final B b = new B();
public static void main(String[] args) {
Class<?> bClass = A.class.getDeclaredClasses()[0];
Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
System.out.println(declaredConstructors.length); //result = 2
}
}
问题是,B类中声明的构造函数等于2。
虽然在其他情况下,B类中的构造函数的数量等于1:
public class A {
private class B
{
public B()
{
}
}
private final B b = new B();
public static void main(String[] args) {
Class<?> bClass = A.class.getDeclaredClasses()[0];
Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
System.out.println(declaredConstructors.length); //result = 1
}
}
和
public class A {
private class B
{
}
public static void main(String[] args) {
Class<?> bClass = A.class.getDeclaredClasses()[0];
Constructor<?>[] declaredConstructors = bClass.getDeclaredConstructors();
System.out.println(declaredConstructors.length); //result = 1
}
}
问题是为什么在第一种情况下有2个构造函数? 谢谢!
答案 0 :(得分:5)
正如chrylis刚刚提到的,你在这里看到的是一个合成构造函数。
基本上,无论何时从嵌套类访问嵌套类的私有属性,编译器都需要为此访问创建synthetic method
。
在你的第一个例子中,默认构造函数是私有的,所以当你调用它时,会创建一个合成方法(因此&#34; 2&#34;构造函数存在)。
在你的第二个例子中,构造函数被声明为public,并且不存在这样的问题。
在您的第三个示例中,它再次是私有的,但也从未被访问过,因此无需创建合成方法。
如果您对更多细节感兴趣,请阅读Java语言规范(https://docs.oracle.com/javase/specs/jls/se7/html/jls-13.html)的第13.1.7节,其中对此进行了进一步说明。
此外,如果您对合成方法的含义感兴趣,这篇文章可能会让您感兴趣,讨论它们在安全性(和性能)方面的含义:What's the penalty for Synthetic methods?
此外,如果您想进一步了解此概念的内部工作原理,我可以推荐以下文章:https://www.javaworld.com/article/2073578/java-s-synthetic-methods.html(据我所知)应该仍然是最新的