java类中的INNERCLASS字段是如何使用的?

java类中的INNERCLASS字段是如何使用的?,java,compiler-construction,bytecode,inner-classes,Java,Compiler Construction,Bytecode,Inner Classes,我看了一些使用ASM的java字节码,当我看到这些行时,我非常惊讶 public class C1 { // compiled from: C1.java // access flags 0x9 public static INNERCLASS C2$C3 C2 C3 //.. } C1对C2中包含的类具有INNERCLASS声明。应该是这样的吗?如果是这样,为什么需要它,它不会导致很多冗余吗 我使用EclipseIndigoSR1编译了一个最小的示例,该示例在外部类型的主

我看了一些使用ASM的java字节码,当我看到这些行时,我非常惊讶

public class C1 {

  // compiled from: C1.java
  // access flags 0x9
  public static INNERCLASS C2$C3 C2 C3

  //..
}
C1
C2
中包含的类具有
INNERCLASS
声明。应该是这样的吗?如果是这样,为什么需要它,它不会导致很多冗余吗

我使用EclipseIndigoSR1编译了一个最小的示例,该示例在外部类型的主方法中有一个内部类型的局部变量。我应该报告错误吗



从:

如果类或接口C的常量池包含至少一个常量类信息条目(§4.4.1),该条目表示不是包成员的类或接口,则C的类文件结构的属性表中必须只有一个InnerClasses属性

也就是说,
InnerClasses
属性引用类文件中引用的所有内部类(“类或接口不是包的成员”),即使它们不是类文件中包含的类的成员。另一种情况(由于缺少特定术语,可能称为外部类)在注释中明确指出:

此外,每个嵌套类和嵌套接口的常量_pool表必须引用其封闭类,因此,每个嵌套类和嵌套接口都将具有每个封闭类及其各自的嵌套类和接口的InnerClass信息


至于为什么需要这些外部引用,我并不完全确定,只是要注意,内部类是在类文件格式基本冻结后在Java 1.1中添加的,因此有关内部类的信息不像超类那样直接存储在
ClassFile
结构(类文件的顶级结构)中,接口、字段和方法都是可用的。还要注意,
InnerClasses
属性是8个字节加上每个被引用的内部类的8个字节——这并不是一个令人望而却步的冗余量。

原始Java文件是什么样子的?你的描述不太清楚。不必是完整的代码,但是看到重要的部分可能会有所帮助;这其实只是我说的;)
public class C1 {
    public static void main(String[] args) throws Exception {
        C2.C3 c3 = new C2.C3();

        ClassReader cr = new ClassReader(C1.class.getName());
        cr.accept(new TraceClassVisitor(new PrintWriter(System.out)), 0);
    }
}
public class C2 {
    public static class C3 {}
}