【问题标题】:How is the INNERCLASS field in java classes used?java类中的INNERCLASS字段是如何使用的?
【发布时间】:2012-07-08 13:43:34
【问题描述】:

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

public class C1 {

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

  //..
}

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

我使用 Eclipse Indigo SR1 编译了一个最小示例,它在外部类型的主要方法中具有内部类型的局部变量,这是值得的。我应该报告错误吗?


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 {}
}

【问题讨论】:

  • 原始Java文件是什么样的?从你的描述中不是很清楚。不必是完整的代码,但查看重要部分可能会有所帮助。
  • 我在问题中添加了确切的测试代码;真的只是我说的;)

标签: java compiler-construction bytecode inner-classes


【解决方案1】:

来自Java Virtual Machine Specification

如果一个类或接口 C 的常量池包含至少一个 CONSTANT_Class_info 条目(第 4.4.1 节),它表示一个不是包成员的类或接口,那么在C类文件结构的属性表。

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

此外,每个嵌套类和嵌套接口的常量池表必须引用它的封闭类,所以总的来说,每个嵌套类和嵌套接口都将具有每个封闭类及其每个嵌套类和接口的 InnerClasses 信息.

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-05-16
    • 1970-01-01
    • 2012-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-29
    相关资源
    最近更新 更多