Java Class 装载机俄罗斯套娃

Java Class Loader Russian Dolls

是否可以在 Java 中创建一个 class 加载器来加载(或更恰当地重新加载)自身?

它最初可以由默认的 classloader 加载。我想象 Java 中的一个系统能够通过编译和加载周期修改自身,因为它是 运行。如果是这样,您可以创建许多继承自俄罗斯套娃加载程序的对象,以动态更新它们的逻辑。

您可以在另一个 ClassLoader 中重新加载每个 class 的 code,其限定名称不以 java. 开头,但这不会重新加载 class。相反,它创建了一个新的 class 具有相同的限定名称但定义不同 ClassLoader.

The Java® Virtual Machine Specification, §5.3. Creation and Loading

A class loader L may create C by defining it directly or by delegating to another class loader. If L creates C directly, we say that L defines C or, equivalently, that L is the defining loader of C.

At run time, a class or interface is determined not by its name alone, but by a pair: its binary name (§4.2.1) and its defining class loader.

因此,当您使用不同的 class 加载程序实例定义与现有的具有相同限定名称的 class 时,您实际上是在创建一个新的运行时 class。当然,class 可能会扩展 ClassLoader 并可用于再次定义具有相同限定名称的新 class。

这些新 class 是否具有相同的字节码,是修改后的版本还是完全不相关的,都没有关系。

这与大多数支持重新加载模块的框架的工作方式很接近。他们创建了一个新的 class 加载器(但不是旧加载器的子加载器),它将“重新加载”模块的 all classes,包括未更改的从技术上讲,它创建了一个新的不相关 classes 的动物园,它们必须相互链接。
旧的 classes 必须超出范围,这需要小心。如果 class 加载器的 class 中的 所有 未被使用,则加载器只能收集垃圾。一个 class 的单个实例可能会阻止其 class 加载器及其所有已定义的 classes 被垃圾收集…