如果类的成员是类或接口,则为 constant_pool表(以及它的InnerClasses属性)必须引用 对每个这样的成员,即使该成员没有另外提及 班级。这些规则意味着嵌套的类或接口成员 将为每个封闭类和for提供InnerClasses信息 每个直接成员。
outer_class_info_index:
如果C 不是某个类的成员或接口(即,如果C a 顶级类或接口(JLS§7.6)或本地类(JLS§14.3) 或匿名类(JLS§15.9.5)),...
您可以从第二段注意到本地类或匿名类不被视为“成员”。这意味着第一段不适用于本地类或匿名类。但是当我编译这段代码时(试过eclipse编译器和javac):
package bc_data;
public class Pokus {
public void metoda() {
class Pokus_Lokalni {
}
}
}
javap -v Pokus.class
Classfile /home/jara/projects/bp/bc_data/src/bc_data/Pokus.class
Last modified May 15, 2015; size 321 bytes
MD5 checksum cf9cd7707c297e7ba43b8408a9ff6e2f
Compiled from "Pokus.java"
public class bc_data.Pokus
SourceFile: "Pokus.java"
InnerClasses:
#5= #4; //Pokus_Lokalni=class bc_data/Pokus$1Pokus_Lokalni
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
您可以看到本地类Pokus_Lokalni
包含在InnerClasses属性中,即使类Pokus
未另外提及它,因此它被视为“成员”?或者为什么本地类Pokus_Lokalni
包含在InnerClasses属性中?它是由规范强制执行的吗?
答案 0 :(得分:2)
我的想法是:
Class.getDeclaredClasses
)。您可以从第二段注意到本地班级或匿名班级不被视为"成员"。
是的,他们不是会员。但它们仍然是内部类,所以它们会正常显示在这里。
答案 1 :(得分:1)
看一下“classes []”部分的第一句话:
constant_pool表中的每个CONSTANT_Class_info条目(表示不是包成员的类或接口C)必须在classes数组中只有一个相应的条目。
这意味着除了顶级以外的所有类都必须包含在InnerClasses中。
现在outer_class_info_index部分:
如果C不是类或接口的成员(即,如果C是顶级类或接口(JLS§7.6)或本地类(JLS§14.3)或匿名类(JLS§) 15.9.5)),outer_class_info_index项的值必须为零。
否则,outer_class_info_index项的值必须是constant_pool表的有效索引,并且该索引处的条目必须是CONSTANT_Class_info(§4.4.1)结构,表示C是其成员的类或接口。
这意味着如果一个类是嵌套的(是另一个类的成员),那么outer_class_info_index必须指向封闭类的CONSTANT_Class_info,但是对于local / anonymous类,存在一个封闭方法而不是封闭类。
在您的情况下,Pokus类没有义务为Pokus_Lokalni提供InnerClasses条目。无论如何,看起来javac包含它,我想我知道为什么。
如果你有一个本地类,那么它可以在声明它的方法中使用,也可以根本不使用(让我们忽略用反射访问它的可能性)。未使用的本地课程似乎是一个非常奇怪和罕见的事情,所以它可能不值得努力以不同的方式对待这种情况。所以javac可能只是在常量池中添加所有本地类(因此在InnerClasses中)。