有没有办法用另一个运行时编译的类取消定义和重新定义类加载器的类?
最佳答案
不,没有办法取消定义类并重新定义它。
您最接近的方法是创建一个新的类加载器并使用它来加载该类的新版本。 “热加载”就是这样实现的。
但是,从 Java 运行时类型系统的角度来看,您实际上是在创建一个新类型。 (JLS 说具有相同完全限定名称和不同类加载器的两个类是不同的类型。)
注意事项:
同时拥有一个类型的多个版本可能会导致不直观的运行时类型错误。
您需要注意 2 个类加载器之间的关系。如果新的以旧的为父,事情会变得相当困惑。
这种事情会导致一些相当隐蔽的内存泄漏。虽然
Class
和ClassLoader
对象可以被垃圾收集,但类加载器、类和实例之间存在一些复杂的(隐藏的)依赖关系,这意味着单个可访问的实例可能会导致类加载器和它所有加载的类仍然可以访问。
为什么没有办法呢?
其中一个原因是,它会严重破坏 JVM 的运行时类型安全性。考虑以下顺序。
加载下面的类
public class Sneaky { public long x = 42; }
创建实例
Sneaky s = new Sneaky();
将类重新定义为新版本
public class Sneaky { public String x; }
尝试使用我们之前创建的对象的
x
字段。System.out.println(s.x.length());
会发生非常糟糕的事情....
关于java - 有没有办法取消定义和重新定义类加载器的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60604281/