Java 为什么编译一个包含静态嵌套类的类会创建一个名为";的新.class文件;随附类别$1“;?
在以下代码中:Java 为什么编译一个包含静态嵌套类的类会创建一个名为";的新.class文件;随附类别$1“;?,java,javac,nested-class,.class-file,Java,Javac,Nested Class,.class File,在以下代码中: class EnclosingClass { public static class BiNode extends Sub.IBiLink { } private static class Sub { private static class IBiLink { } } } 在与其他.class文件一起编译时,我还看到一个名为“EnclosingClass$1.class”
class EnclosingClass
{
public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}
在与其他.class文件一起编译时,我还看到一个名为“EnclosingClass$1.class”的文件。为什么会自动创建这个文件?发生了什么?首先查看JVM规范中的类访问和属性修饰符表 请注意
ACC\u SYNTHETIC
标志,该标志指定源代码中不存在它(简单地说,它将在编译器生成类时添加)
让我们看一下
封闭类$1.class的字节码(注意,我只粘贴重要的部分)
产生以下结果
Classfile /C:/Users/jfrancoiss/Desktop/Nouveau dossier/EnclosingClass$1.class
Last modified 2015-03-31; size 190 bytes
MD5 checksum 5875440f1e7f5ea9a519d02fbec6dc8f
Compiled from "EnclosingClass.java"
class EnclosingClass$1
minor version: 0
major version: 52
flags: ACC_SUPER, ACC_SYNTHETIC
注意,类的访问标志包含ACC\u SYNTHETIC
ACC_合成标志表示该类或接口已
由编译器生成,不出现在源代码中
确保生成的类是合成类的另一个选项是编译为
javac -XD-printflat EnclosingClass.java
那会产生什么
/*synthetic*/ class EnclosingClass$1 {
}
很好,但是为什么要生成一个合成类呢
Java反射教程可以帮助我们理解这一点。看一下课堂上的评论
因此,根据注释,创建了包含$1.class的合成类是因为IBiLink
是私有的
再一次,在这一点上指定
因为内部类的构造函数引用私有构造函数
对于封闭类,编译器必须生成私有包
构造器
在我们的例子中,我们没有明确看到任何构造函数调用,但我们有这一行
public static class BiNode extends Sub.IBiLink { }
让我们试着编译这段代码,看看会发生什么
class EnclosingClass
{
//public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}
无EnclosingClass$1。已生成类
调试时注意到的更多详细信息
改变
private static class IBiLink
到
请注意,编译时,不会创建封闭类$1.class
为什么保护类不会生成合成类
这仅仅是因为在保护类时,您可以隐式地访问每个超类
为什么eclipse编译器不生成合成类?
Eclipse使用它的内置编译器,您可以配置它的严重性级别
默认情况下,对封闭类型的不可访问成员的访问设置为忽略,如您在此图像上所示
例如,将其更改为“警告”,您将收到以下消息
这让我相信eclipse不会创建其他类,而是会模拟它来模拟合成成员。这里定义的所有内部类都是静态的,eclipse编译器不会生成这样的类文件<代码>JavaC1.8.0_20。根据规范afaik,不需要这样的.class文件。这可能会使javac变得更容易。当IBiLink
声明为包本地时,不会生成包含$1的包,尽管我不明白为什么。您描述的类签名是用于匿名内部类的。@vsnyc Nice find。第二个(也是投票最高的)答案更令人满意,因为Oak似乎有一个似是而非的答案。
class EnclosingClass
{
//public static class BiNode extends Sub.IBiLink { }
private static class Sub
{
private static class IBiLink
{
}
}
}
private static class IBiLink
protected static class IBiLink