内部类属性
InnerClasses attribute
If a class has members that are classes or interfaces, its
constant_pool table (and hence its InnerClasses attribute) must refer
to each such member, even if that member is not otherwise mentioned by
the class. These rules imply that a nested class or interface member
will have InnerClasses information for each enclosing class and for
each immediate member.
outer_class_info_index:
If C is not a member of a class or an interface (that is, if C is a
top-level class or interface (JLS §7.6) or a local class (JLS §14.3)
or an anonymous class (JLS §15.9.5)), ...
您可以从第二段中注意到,本地 class 或匿名 class 不会被视为 "members"。这意味着第一段不适用于本地 classes 或匿名 classes。但是当我编译这段代码时(试过 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/PokusPokus_Lokalni
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
可以看到局部的classPokus_Lokalni
即使在classPokus
中没有另外提及,也包含在InnerClasses属性中,所以被处理作为 "member"?或者为什么局部class Pokus_Lokalni
包含在InnerClasses属性中?它在某处由规范强制执行?
看看 "classes[]" 部分的第一条语句:
Every CONSTANT_Class_info entry in the constant_pool table which represents a class or interface C that is not a package member must have exactly one corresponding entry in the classes array.
这意味着除顶级之外的所有 class 类都必须包含在 InnerClasses 中。
现在outer_class_info_index节:
If C is not a member of a class or an interface (that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5)), the value of the outer_class_info_index item must be zero.
Otherwise, the value of the outer_class_info_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Class_info (§4.4.1) structure representing the class or interface of which C is a member.
这意味着如果 class 是嵌套的(是另一个 class 的成员),那么 outer_class_info_index 必须指向封闭的 class 的 CONSTANT_Class_info , 但对于 local/anonymous class 存在一个封闭方法而不是封闭 class.
在您的情况下,Pokus class 没有义务为 Pokus_Lokalni 输入 InnerClasses。看起来 javac 无论如何都包含它,我想我知道为什么了。
如果你有一个本地 class 那么它要么在声明它的方法中使用,要么根本不使用(让我们忽略通过反射访问它的可能性)。 Unused local class 似乎是一件非常奇怪和罕见的事情,因此可能不值得以不同的方式对待这种情况。因此 javac 可能只是将所有本地 classes 添加到常量池中(因此在 InnerClasses 中)。
我的想法是:
- class 文件中的包含需要 强制 成员 class 出于反映的目的(因为例如
Class.getDeclaredClasses
).
- 本地和匿名 classes 并非如此,但没有理由不能存储它们,即使它不是强制性的。
You can notice from the second paragraph that a local class or an anonymous class are not treated as "members".
是的,他们不是会员。不过,它们仍然是内部 classes,所以它们会正常出现在这里。
If a class has members that are classes or interfaces, its constant_pool table (and hence its InnerClasses attribute) must refer to each such member, even if that member is not otherwise mentioned by the class. These rules imply that a nested class or interface member will have InnerClasses information for each enclosing class and for each immediate member.
outer_class_info_index:
If C is not a member of a class or an interface (that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5)), ...
您可以从第二段中注意到,本地 class 或匿名 class 不会被视为 "members"。这意味着第一段不适用于本地 classes 或匿名 classes。但是当我编译这段代码时(试过 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/PokusPokus_Lokalni
minor version: 0
major version: 51
flags: ACC_PUBLIC, ACC_SUPER
可以看到局部的classPokus_Lokalni
即使在classPokus
中没有另外提及,也包含在InnerClasses属性中,所以被处理作为 "member"?或者为什么局部class Pokus_Lokalni
包含在InnerClasses属性中?它在某处由规范强制执行?
看看 "classes[]" 部分的第一条语句:
Every CONSTANT_Class_info entry in the constant_pool table which represents a class or interface C that is not a package member must have exactly one corresponding entry in the classes array.
这意味着除顶级之外的所有 class 类都必须包含在 InnerClasses 中。
现在outer_class_info_index节:
If C is not a member of a class or an interface (that is, if C is a top-level class or interface (JLS §7.6) or a local class (JLS §14.3) or an anonymous class (JLS §15.9.5)), the value of the outer_class_info_index item must be zero.
Otherwise, the value of the outer_class_info_index item must be a valid index into the constant_pool table, and the entry at that index must be a CONSTANT_Class_info (§4.4.1) structure representing the class or interface of which C is a member.
这意味着如果 class 是嵌套的(是另一个 class 的成员),那么 outer_class_info_index 必须指向封闭的 class 的 CONSTANT_Class_info , 但对于 local/anonymous class 存在一个封闭方法而不是封闭 class.
在您的情况下,Pokus class 没有义务为 Pokus_Lokalni 输入 InnerClasses。看起来 javac 无论如何都包含它,我想我知道为什么了。
如果你有一个本地 class 那么它要么在声明它的方法中使用,要么根本不使用(让我们忽略通过反射访问它的可能性)。 Unused local class 似乎是一件非常奇怪和罕见的事情,因此可能不值得以不同的方式对待这种情况。因此 javac 可能只是将所有本地 classes 添加到常量池中(因此在 InnerClasses 中)。
我的想法是:
- class 文件中的包含需要 强制 成员 class 出于反映的目的(因为例如
Class.getDeclaredClasses
). - 本地和匿名 classes 并非如此,但没有理由不能存储它们,即使它不是强制性的。
You can notice from the second paragraph that a local class or an anonymous class are not treated as "members".
是的,他们不是会员。不过,它们仍然是内部 classes,所以它们会正常出现在这里。