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

标签 java reflection

我有一个公共(public)类(class),里面有一个私有(private)类(class):

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 中声明的构造函数等于二。

虽然在其他情况下,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 已经简短提到的,您在这里看到的是一个合成构造函数。

基本上,每当您从嵌套类访问嵌套类的私有(private)属性时,编译器都需要为此访问创建一个合成方法

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

在你的第二个例子中,构造函数被声明为公共(public)的,不存在这样的问题。

在您的第三个示例中,它再次是私有(private)的,但也从未访问过,因此无需创建合成方法。

如果您对更多细节感兴趣,请阅读 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 - 内部类中的两个声明的构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49105076/

相关文章:

java - 如何将列表转换为可变参数参数java

java - 大 O 表示法 : Justifying f(n) ∈ O(n^4)?

java - postdelayed Handler 不会重复运行

java - 如何在不知道类的包的情况下实例化一个类?

java - 动态修改字段注解值

java - 访问已安装认证签名

java - Eclipse IDE 无法识别 mysql 驱动程序

java - sonarQube 是否检测反射 api 调用的未使用方法

reflection - Kotlin 检查函数是否需要实例参数

c# - 在新应用程序域上创建动态程序集