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

标签 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 声明。这是应该的样子吗?如果是这样,为什么需要它,这不会导致很多冗余吗?

我使用 Eclipse Indigo SR1 编译了一个最小示例,该示例在外部类型的 main 方法中具有内部类型的局部变量,无论其值(value)如何。我应该报告错误吗?

<小时/>
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 Virtual Machine Specification :

If the constant pool of a class or interface C contains at least one CONSTANT_Class_info entry (§4.4.1) which represents a class or interface that is not a member of a package, then there must be exactly one InnerClasses attribute in the attributes table of the ClassFile structure for C.

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

In addition, the constant_pool table of every nested class and nested interface must refer to its enclosing class, so altogether, every nested class and nested interface will have InnerClasses information for each enclosing class and for each of its own nested classes and interfaces.

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

关于java - java类中的INNERCLASS字段是如何使用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11383600/

相关文章:

java - 使用数据库连接池的开销

java - 在 Java 中使用 UUID 的最高有效位发生冲突的可能性

c++ - 间接运算符的 C++ 标准描述是否保证不会优化内存写入?

compiler-construction - Writing a temporary compiler 用新语言写一个编译器

java.lang.VerifyError : Stack map does not match the one at exception handler

java - 什么调用类初始化方法 <clinit> 以及何时调用?

java - 如何在 gradle 3 或更高版本中使用 jar 文件?

java - 如何在 libGDX 中显示 Admob 插页式广告

java - 编译在运行时引用当前程序类的Java代码

java - 使用 ASM 查找 "implicit"变量的通用签名