反射是针对类加载器的吗?

Is reflection is for classloader?

我知道反射是一种在不知道具体类型的情况下调用方法或操纵字节码的技术。

最近在研究classloader的时候看到一篇文章说反射是为了classloader动态加载类和做类型检查。这是真的吗?

文章

原文不是英文,所以翻译的可能有点奇怪。

Java dynamically loads classes. That is, all code is linked to the JVM at runtime. Every class is dynamically linked to the JVM and loaded into memory at the moment that class is referenced. Java's runtime library ([JDK installation directory]/jre/lib/rt.jar) is no exception. This dynamic class loading is done through the class loader system of Java, and the class loader provided by Java is expressed through java.lang.ClassLoader. When the JVM starts, it creates a bootstrap class loader and then reads the first class, Object, into the system.

Loading a class dynamically at runtime means that the JVM has no information about the class. In other words, the JVM does not know information about methods, fields, and inheritance relationships of classes. Therefore, the classloader should be able to obtain the necessary information when loading a class and check whether the class is correct. If you can't do this, the JVM may have mismatched versions of the .class files, and it will be impossible to type-check. The JVM has the ability to analyze classes internally, and from JDK 1.1, developers can analyze these classes through reflection.

反射特别是 Java 代码 检查已经加载的 Java classes 并与它们动态交互的能力(即不只需调用编译时已知的方法或访问字段。

JVM 在加载 class 时所做的类似,因为它检查字节码以了解组成 class 的部分并检查正确性,但这不是反射在上面写的意义上:它确实 not 使用相同的 API,因为它们仅限于更高级别的视图。实际上,Java 中的反射 API 只有在 JVM 已经完全分析并“理解”class.

后才会发挥作用

请注意,classloader 本身实际上并不需要理解 classes:它只向 JVM 提供原始字节码来加载它们。它所要做的就是找到该字节码并将其加载到内存中

Is reflection is for classloader?

基本上...没有。

大多数 classloader Java 代码都是关于在 class 路径上查找 classes 和资源。当它决定需要加载 class 时,它会调用一个内部本机方法将(通常)包含 class 文件表示的 byte[]ByteBuffer 转换为加载的 class。该本机方法使用的基础结构位于常规 Java 代码使用的反射 API 之下。

另一方面,应用程序对很多事情都使用反射,所以即使 classloader 确实使用了反射,你也不能说反射是 for class装载机。它是 for ... 很多东西。

反思是一个有点生硬的术语...但一般的想法是它是关于一个程序看着思考 本身。在这种情况下,JVM 不是程序。它是运行程序的机器。 Class 加载和维护运行时类型安全是 JVM 的基本功能...而反射 API 是 JVM 提供给 (Java 等的 服务 ) JVM 上/中的应用程序 运行。


还有...

I know that reflection is a technique for ... manipulating bytecode ...

实际上,反射不允许您在传统意义上“操纵”字节码。那种事情(所谓的“字节码工程”)是由不同类型的库完成的。它发生在字节码加载之前。


有点难以理解引用的文字实际上在说什么,尤其是因为翻译。但我不认为它是说 classloader 需要 使用反射。

Therefore, the classloader should be able to obtain the necessary information when loading a class and check whether the class is correct.

正确。

If you can't do this, the JVM may have mismatched versions of the .class files, and it will be impossible to type-check.

正确。

The JVM has the ability to analyze classes internally,

正确。但它并没有说 JVM 正在使用反射来执行此操作。它正在使用(未指定的)内部机制。它们不涉及调用反射 API。即使在 Java 1.0 / 1.1 天 ClassLoader class 负责链接和验证(根据@Holger 的回答),他们也会直接解析 class 文件而不是比使用反射 API。

and from JDK 1.1, developers can analyze these classes through reflection.

这有点不合逻辑……但我认为正确的阅读方式是开发人员可以 访问类型信息。这并不是说 classloader 和 Java 程序使用相同的(反射)API 来访问类型信息。

综上所述,我认为您误读了文章的内容。

引用的文本中没有任何内容可以得出反射是“用于 classloader”的结论。

文本以“……并且从 JDK 1.1 开始,开发人员可以通过反射分析这些 classes”,这是代表其自身的附加信息。之前文中讲到 class 加载器,与这里无关。

当它归结为“实际上从一开始”时提到版本号,表明这是一个相当古老的文本。这部分解释了

Therefore, the classloader should be able to obtain the necessary information when loading a class and check whether the class is correct.

Class 加载程序根本不这样做。但是在 Java 1.0 和部分 Java 1.1 中,class 加载程序确实被认为负责链接和验证任务。这已通过 JDK 1.2(也称为 Java 2)进行了清理。从那时起,class 加载程序的职责仅限于定位必要的资源并将其加载到字节数组中,以传递给 JVM。链接和验证是 JVM 的工作,这意味着它还将保护自己免受可能损坏的 class 加载程序。

由于 class 加载程序的工作只是将文件、套接字或其他资源读入字节数组并将它们传递给 JVM,因此它们本身不需要反射 API。