Java 为什么classname$1.class会在这种情况下生成?
我编写了以下代码来实现Singleton模式:Java 为什么classname$1.class会在这种情况下生成?,java,compilation,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.I
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。这没有道理。那么,这是为什么以及如何实现的呢?类
TestHolder
需要在Test
中调用私有构造函数。但它是私有的,实际上不能从其他类调用。因此,编译器在玩一个把戏。它向测试添加了一个新的非私有构造函数,只有它知道!该构造函数获取这个匿名类的一个(未使用的)实例Test$1
——没有人知道它的存在。然后TestHolder
创建一个Test$1
的实例,并调用该构造函数,该构造函数是可访问的(默认受保护)
您可以使用javap-ctest
(和javap-ctest\$1
,以及javap-ctest\$TestHolder
)查看代码。事实上,它相当聪明 @sircapsalot问题是匿名类在哪里。这是值得投票的问题类型。我在这里没有Test$1.class
文件(JDK 7或6)。还有其他人吗?是的,JavaC1.6.045
在我的Mac上创建了它,我在下面解释了它的用途。反编译字节码支持这个答案-静态内部类测试$1测试null
。答案很好,实现巧妙。你是不是碰巧在脑子里知道这件事?@Vulcan,不,我不知道。认为这是一个有趣的问题,编译了代码,用javap
检查了它,并解释了我的发现。不应该是javap-c Test$1
和javap-c Test$TestHolder
,而不是。\$
?呵呵。类Unix系统上需要反斜杠,但Windows上不需要反斜杠。