内部类中有两个声明的构造函数

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了内部类中有两个声明的构造函数相关的知识,希望对你有一定的参考价值。

我有一个公共类,里面有一个私有类:

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类中的构造函数的数量等于一:

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个构造函数?谢谢!

答案

正如chrylis刚刚提到的,你在这里看到的是一个合成构造函数。

基本上,无论何时从嵌套类访问嵌套类的私有属性,编译器都需要为此访问创建synthetic method

在第一个示例中,默认构造函数是私有的,因此在调用它时会创建一个合成方法(因此存在“2”构造函数)。

在第二个示例中,构造函数被声明为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(据我所知)应该仍然是最新的)

以上是关于内部类中有两个声明的构造函数的主要内容,如果未能解决你的问题,请参考以下文章

内部类中的私有构造函数在外部类中初始化

在类中声明数组并在构造函数中初始化

JAVA中抽象类的一些总结

继承20161223

C++学习 之 类中的特殊函数和this指针

在内部片段类中使用ListView