Java 内部类属性

Java 内部类属性,java,class,jvm,Java,Class,Jvm,描述说 如果类的成员是类或接口,则其 常量池表(以及它的InnerClasses属性)必须引用 各成员,即使该成员未被 这个班。这些规则意味着嵌套类或接口成员 将具有每个封闭类和的内部类信息 每个直接成员 外部类信息索引: 如果C不是类或接口的成员(也就是说,如果C是a 顶级类或接口(JLS§7.6)或本地类(JLS§14.3) 或匿名类(JLS§15.9.5)) 从第二段可以注意到,本地类或匿名类不被视为“成员”。这意味着第一段不适用于本地类或匿名类。但是当我编译这段代码时(尝试了eclips

描述说

如果类的成员是类或接口,则其 常量池表(以及它的InnerClasses属性)必须引用 各成员,即使该成员未被 这个班。这些规则意味着嵌套类或接口成员 将具有每个封闭类和的内部类信息 每个直接成员

外部类信息索引:

如果C不是类或接口的成员(也就是说,如果C是a 顶级类或接口(JLS§7.6)或本地类(JLS§14.3) 或匿名类(JLS§15.9.5))

从第二段可以注意到,本地类或匿名类不被视为“成员”。这意味着第一段不适用于本地类或匿名类。但是当我编译这段代码时(尝试了eclipse编译器和javac):

bc\u数据包;
公共类Pokus{
公共空间{
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属性中?它是由某个地方的规范强制执行的?

请查看“classes[]”部分的第一条语句:

CONSTANT_pool表中表示非包成员的类或接口C的每个CONSTANT_Class_info条目在classes数组中必须正好有一个对应条目

这意味着除顶级之外的所有类都必须包含在InnerClass中

现在外部类信息索引部分:

如果C不是类或接口的成员(即,如果C是顶级类或接口(JLS§7.6)、本地类(JLS§14.3)或匿名类(JLS§15.9.5)),则外部类信息索引项的值必须为零

否则,外部_class_info_索引项的值必须是常量_池表中的有效索引,并且该索引处的条目必须是常量_class_info(§4.4.1)结构,表示C是其成员的类或接口

这意味着,如果一个类是嵌套的(是另一个类的成员),那么外部类信息索引必须指向封闭类的常量类信息,但是对于本地/匿名类,存在一个封闭方法而不是封闭类

在您的情况下,Pokus类没有义务为Pokus_Lokalni设置内部类条目。看起来javac包含了它,我想我知道为什么了


如果您有一个本地类,那么它要么在声明它的方法中使用,要么根本不使用(让我们忽略通过反射访问它的可能性)。未使用的本地类似乎是非常奇怪和罕见的事情,所以可能不值得尝试以不同的方式对待这种情况。所以javac可能只是将所有本地类添加到常量池中(因此也添加到内部类中)。

我的想法如下:

  • 出于反射的目的,需要强制成员类包含在类文件中(例如)
  • 本地类和匿名类的情况并非如此,但没有理由不存储它们,即使它们不是强制的
从第二段可以注意到,本地类或匿名类不被视为“成员”


是的,他们不是会员。不过,它们仍然是内部类,因此通常会显示在这里。

是常量池表中的每个常量\u类\u信息条目。但要获得该条目,您需要以某种方式使用该类。正如你所看到的,我没有使用它,只是声明了它。如果它被视为“成员”,那么它将由规范强制执行,但除此之外??好的,现在我看到了这一点,首先为误解感到抱歉。看起来javac只是发布了额外的常量池条目,即使它可能选择不这样做。更新了我的答案,并考虑到了这一点。“所以第二段说,本地类或匿名类不被视为“成员”。”第二段指的是与第一段无关的内容,所以它与第一段无关。但我明白了除此之外您所问的。@Radiodef:是的,我将对其进行一点修改,即认为它们仍然是内部类是可以的,但为什么规范明确说明了嵌套成员(它们必须在常量池中有条目),而没有说明嵌套的“非成员”(本地和匿名类)?我只是想知道我是否可以确定(如果它是由规范强制执行的),即使没有使用本地或匿名类,也将始终在InnerClasses属性中有条目。我在回答中说,成员类需要通过反射可用,因此需要保证它们在类文件中有条目。Anonymous和local不需要这种保证,我也不知道有这样的保证。