JVM 如何决定一个类是否“属于”类? (例如内部类或嵌套类)到另一个类?

发布于 2024-12-14 21:53:58 字数 715 浏览 2 评论 0原文

我想更好地理解类文件和内部/嵌套类,我想知道以下事情:

  • InnerClasses 属性是否用于引用“包含”类中的内部/嵌套类或它是否在内部/嵌套类中用于引用“容器”类?
  • 类文件中的 InnerClasses 属性是否足够?例如,内部/嵌套类是否必须遵循带有 $ 的名称修饰,或者这只是一个约定?
  • 有没有一种方法可以使类在 JVM 中看起来像内部/嵌套类,而无需设置 InnerClasses 属性,这是否取决于 JLM 供应商? (我记得听说IBM的实现在某些部分要求不太严格。)
  • JVM的类加载机制与Java反射有多少交互?是否有可能使 JVM 不同意 Java 反射的结果?

我尝试在 JVM 规范中查找它,但没有找到实际机制的描述。

我只在“The ”中找到了这句话InnerClasses Attribute” 远程连接到我的问题:

Java虚拟机当前不检查一致性 任何实际代表一个类文件的 InnerClasses 属性 属性引用的类或接口。

I want to understand class files and inner/nested classes a bit better and I'm wondering about the following things:

  • Is the InnerClasses attribute used to refer tothe inner/nested classes in the ´containing´ class or is it used in the inner/nested classes to refer to the ‘container’ class?
  • Is the InnerClasses attribute in class files sufficient? E.g. Do inner/nested classes have to follow the name mangling with $ or is this just a convention?
  • Is there a way to make a class look like an inner/nested class to the JVM without setting the InnerClasses attribute and does this depend on the JLM vendor? (I remember hearing that IBM's implementation had less strict requirements in some parts.)
  • How much does the class loading mechanism of the JVM interact with Java reflection? Would it be possible to make the JVM disagree with the results from Java reflection?

I tried looking it up in the JVM specification but didn't find a description of the actual mechanism.

I only found this sentence in “The InnerClasses Attribute” remotely connected to my question:

The Java virtual machine does not currently check the consistency of
the InnerClasses attribute with any class file actually representing a
class or interface referenced by the attribute.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

耶耶耶 2024-12-21 21:53:59

对之前的回答做一些补充:

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

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

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

是否有一种方法可以使类在 JVM 中看起来像内部/嵌套类,而无需设置 InnerClasses 属性,这是否取决于 JLM 供应商? (我记得听说IBM的实现在某些部分的要求不太严格。)

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

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

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

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

A few additions to the previous answer:

Is the InnerClasses attribute used to store the contained inner/nested classes in the containing class or is it used in the inner/nested classes to refer to the ‘container’ class?

The bytecode of every compiled class is stored in a separate .class file. The the actual "inner classes" are not stored in that attribute. As the previous post pointed out, that attribute only points to classes that the compiler knew about when creating the bytecode.

Is the InnerClasses attribute in class files sufficient? E.g. Do inner/nested classes have to follow the name mangling with $ or is this just a convention?

Is there a way to make a class look like an inner/nested class to the JVM without setting the InnerClasses attribute and does this depend on the JLM vendor? (I remember hearing that IBM's implementation had less strict requirements in some parts.)

For both questions, I am not certain. But I think the concept of inner/nested classes is something that the Java language (and hence the Java compiler provides). In the bytecode, there should not be any difference between a class that was declared as a normal public class and some nested or inner class.
You could easily try out how an given VM handles this like so:

  • Create a class with some nested and inner classes
  • Write a little program that tries to load and instantiate one of the inner classes through reflection from outside the scope of defining class. You must use reflection here, because the Java compiler will not allow you to instantiate a nested class that is not in scope! If you can successfully instantiate the class, that is evidence that internally the VM does not handle nested and normal classes differently.

How much does the class loading mechanism of the JVM interact with Java reflection? Would it be possible to make the JVM disagree with the results from Java reflection?

I don't understand this last question. Could you explain a bit more what you mean when you say the VM and reflection should disagree?

夏花。依旧 2024-12-21 21:53:59

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

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

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

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

是否有一种方法可以使类在 JVM 中看起来像内部/嵌套类,而无需设置内部类属性,这是否取决于 JLM 供应商? (我记得听说IBM的实现在某些部分的要求不太严格。)

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

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

我不相信类加载器使用反射。然而,反射可能从类加载器所在的同一位置获取其信息。我不明白为什么这很重要。

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

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

I know that there is an inner class attribute in class files, but is this sufficient?

The InnerClasses attribute is in the byte code and it lists all the known inner classes of the outer class. This is not something you can use directly.

E.g. Do inner/nested classes have to follow the name mangling with $ or is this just a convention?

The compiler will follow this convention and you have no control over it.

Is there a way to make a class look like an inner/nested class to the JVM without setting the inner class attribute and does this depend on the JLM vendor? (I remember hearing that IBM's implementation had less strict requirements in some parts.)

You can create a class with the same name. YOu cna try that for yourself.

How much does the class loading mechanism of the JVM interact with Java reflection?

I don't believe the class loader uses reflection. However reflection may get its information from the same place the class loader does. I don't see why it would matter.

Would it be possible to make the JVM disagree with the results from Java reflection?

You can use reflection to corrupt the data in reflection based objects. Again, not sure why you would want to do this.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文