类装入器的常见用途是隔离 JAR。如果你有一个使用插件的应用程序(Eclipse,Maven 2),那么你可能会遇到这种情况:插件X需要1.0版的jar A,而插件Y需要相同的jar,但版本2.0。但是,X 不能在 2.0 版中运行。
如果你有类装入器,你可以创建类的分区(想想由细桥连接的孤立岛;桥是类装入器)。这样,类加载器可以控制每个插件可以看到的内容。
当插件X实例化具有静态字段的类Foo时,这没有问题,并且不会与插件Y中的“相同”类混淆,因为每个类加载器实际上都会创建自己的类Foo实例。然后,内存中有两个类,其中是,但不是。这意味着 cl1 的实例与 cl2 的实例不兼容。这可能会导致奇怪的说,无法分配给 .cl1.getName().equals(cl2.getName())
true
cl1.equals(cl2)
ClassCastExceptions
org.project.Foo
org.project.Foo
就像偏远的岛屿一样,这两个类都不知道另一个类的存在。想想人类克隆,它们在不同的岛屿上出生和长大。从 VM 的角度来看,没有问题,因为 Class 类型的实例的处理方式与任何其他对象类似:可以有多个实例。你认为其中一些是“相同的”对 VM 并不重要。
此模式的另一个用途是,您可以摆脱以这种方式加载的类:只需确保没有人有指向从类装入器装入的类创建的任何对象的指针,然后也忘记类装入器。在下一次运行 GC 时,将从内存中删除由此类装入器装入的所有类。这样,您就可以“重新加载”应用程序,而无需重新启动整个 VM。