Java 类加载器俄罗斯套娃

标签 java compilation jvm classloader dynamic-class-loaders

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

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

最佳答案

您可以在另一个 ClassLoader 中重新加载限定名称不以 java. 开头的每个类的代码,但这不会重新加载类。相反,它会创建一个具有相同限定名称但定义不同的 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.

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

这些新类是否具有相同的字节码,是修改后的版本还是完全不相关的,都无关紧要。

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

关于Java 类加载器俄罗斯套娃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38001302/

相关文章:

java - 如何使用正则表达式java获取两个字符之间的数字?

java - Playframework [Java] : provision error (com. google.inject.ProvisionException)

java - 如何从现有的jhipster项目中获取JDL或JH文件

c++ - 部署使用 C++ 开发的应用程序

C++编译静态变量和共享对象

java - 从命令行编译

从 Java 8 迁移到 Java 10。在生产环境中运行服务

java - 识别 Java jdwp 调试器分配的(临时)端口

java - Sun permgen 和 JRockit 垃圾收集

java - 如何在 Activity 开始时在进度条上显示进度