6
4

2 回答 2

2

对上一个答案的一些补充:

InnerClasses 属性是用于在包含类中存储包含的内部/嵌套类,还是在内部/嵌套类中用于引用“容器”类?

每个已编译类的字节码都存储在一个单独的 .class 文件中。实际的“内部类”不存储在该属性中。正如上一篇文章所指出的,该属性仅指向编译器在创建字节码时知道的类。

类文件中的 InnerClasses 属性是否足够?例如,内部/嵌套类是否必须遵循使用 $ 修饰的名称,或者这只是一个约定?

有没有办法在不设置 InnerClasses 属性的情况下使类看起来像 JVM 的内部/嵌套类,这是否取决于 JLM 供应商?(我记得听说 IBM 的实施在某些部分的要求不那么严格。)

对于这两个问题,我都不确定。但我认为内部/嵌套类的概念是 Java 语言(因此 Java 编译器提供)的东西。在字节码中,声明为普通公共类的类与某些嵌套类或内部类之间不应有任何区别。您可以轻松地尝试给定的虚拟机如何处理这个问题,如下所示:

  • 创建一个包含一些嵌套类和内部类的类
  • 编写一个小程序,尝试通过定义类范围之外的反射来加载和实例化其中一个内部类。您必须在此处使用反射,因为 Java 编译器不允许您实例化不在范围内的嵌套类!如果您可以成功实例化该类,则证明 VM 在内部不会以不同方式处理嵌套类和普通类。

JVM 的类加载机制与 Java 反射有多大的交互作用?是否有可能使 JVM 不同意 Java 反射的结果?

我不明白最后这个问题。当您说虚拟机和反射应该不同意时,您能否解释一下您的意思?

于 2012-02-24T09:50:06.790 回答
1

我知道类文件中有一个内部类属性,但这是否足够?

InnerClasses 属性位于字节码中,它列出了外部类的所有已知内部类。这不是您可以直接使用的东西。

例如,内部/嵌套类是否必须遵循使用 $ 修饰的名称,或者这只是一个约定?

编译器将遵循此约定,您无法控制它。

有没有办法在不设置内部类属性的情况下使类看起来像 JVM 的内部/嵌套类,这是否取决于 JLM 供应商?(我记得听说 IBM 的实施在某些部分的要求不那么严格。)

您可以创建一个具有相同名称的类。你可以自己试试。

JVM 的类加载机制与 Java 反射有多大的交互作用?

我不相信类加载器使用反射。然而,反射可能会从类加载器的同一个地方获取它的信息。我不明白为什么这很重要。

是否有可能使 JVM 不同意 Java 反射的结果?

您可以使用反射来破坏基于反射的对象中的数据。同样,不确定您为什么要这样做。

于 2011-11-10T15:51:55.573 回答