我编写了以下代码来实现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;
}
}
当我编译这个文件时,它应该生成Test.class和Test $ TestHolder.class,但它也会生成Test $ 1.class。这没有意义。那么为什么以及如何呢?
答案 0 :(得分:28)
类TestHolder
需要在Test
中调用私有构造函数。但它是私有的,实际上不能从另一个类调用。所以编译器起了作用。它向Test
添加了一个新的非私有构造函数,只有它知道!该构造函数接受这个匿名类Test$1
的一个(未使用过的)实例 - 没人知道存在。然后TestHolder
创建Test$1
的实例,并调用 构造函数,该构造函数是可访问的(它是默认保护的。)
您可以使用javap -c Test
(以及javap -c Test\$1
和javap -c Test\$TestHolder
)查看代码。实际上它非常聪明!