为什么classname $ 1.class会在这种情况下生成?

han*_*ang 27 java compilation

我编写了以下代码来实现Singleton模式:

public final class Test {
     static final class TestHolder {
         private static final Test INSTANCE = new Test();
     }     

     private Test() {}

     public static Test getInstance() {
         return TestHolder.INSTANCE;
     }
}
Run Code Online (Sandbox Code Playgroud)

当我编译这个文件时,它应该生成Test.class和Test $ TestHolder.class,但它也会生成Test $ 1.class.这没有意义.那么为什么以及如何呢?

Ern*_*ill 28

TestHolder需要调用私有构造函数Test.但它是私有的,实际上不能从另一个类调用.所以编译器起了作用.它添加了一个新的非私有构造函数Test,只有它知道!该构造函数接受此匿名类的一个(未使用的)实例Test$1- 没有人知道它存在.然后TestHolder创建一个实例Test$1并调用构造函数,该构造函数是可访问的(它是默认保护的.)

您可以使用javap -c Test(和javap -c Test\$1,javap -c Test\$TestHolder)查看代码.实际上,它非常聪明!