谁能给我指出一个好的资源或向我解释类加载器背后的概念?我在类加载器上找到了以下资源 http://www.onjava.com/lpt/a/5586 但仍然没有帮助。以下问题可能看起来很愚蠢,但试图回答它们总是让我感到困惑。

  • 为什么开发人员要编写自定义类加载器,为什么不调用 Bootstrap 类加载器来调用您的自定义类?什么情况下需要定义自定义类加载器?
  • 为什么类加载器有这么多种类?例如:Bootsrap、Comman、Catalina 类加载器等,

    提前致谢。

有帮助吗?

解决方案

我发现了以下创建自定义类加载器的正当理由:

  1. 您想要从非常规源加载一个类(例如,一个类的字节码存储在数据库中,通过网络或 由 pidgeons 携带 0 和 1 - MessengerPidgeonClassLoader)。对于这种情况,API 中已经有一些 ClassLoader 实现,例如 URL类加载器.

  2. 您需要定义不同的层次结构来加载类。ClassLoader 的默认实现首先将搜索委托给父级,然后它们尝试自己加载类。也许您想要不同的层次结构。这就是为什么 OSGI 和 Eclipse 有自己的类加载器,因为 Manifest .MF 文件定义了所有类型的奇怪层次路径(例如伙伴类加载)。所有 Eclipse 类加载器都实现 BundleClassLoader 接口,并有一些额外的代码来查找 Eclipse 插件中的资源。

  3. 您需要对字节码进行一些修改。也许字节码已加密,您将即时解密它(并不是说它确实有帮助,但已经尝试过)。也许您想“修补”动态加载的类(A la JDO 字节码增强)。

如果您需要从内存中卸载类,或者加载可能在运行时更改其定义的类,则需要使用与系统类加载器不同的类加载器。例如,典型的情况是应用程序从 XML 文件动态生成一个类,然后尝试重新加载该类。一旦类位于系统类加载器中,就无法将其卸载并获得新的定义。

其他提示

类加载器的常见用途是隔离 JAR。如果您有一个使用插件的应用程序(, 行家2),那么你可能会遇到这样的情况:插件 X 需要版本 1.0 的 jar A,而插件 Y 需要相同的 jar,但版本 2.0。不过,X 不能与 2.0 版本一起运行。

如果您有类加载器,则可以创建类的分区(想象一下由细桥连接的孤岛;桥是类加载器)。这样,类加载器就可以控制每个插件可以看到的内容。

当插件 X 实例化具有静态字段的类 Foo 时,这没有问题,并且不会与插件 Y 中的“相同”类发生混淆,因为每个类加载器实际上都会创建自己的类 Foo 的实例。然后你的内存中有两个类,其中 cl1.getName().equals(cl2.getName())truecl1.equals(cl2) 不是。这意味着 cl1 的实例与 cl2 的实例分配不兼容。这可能会导致奇怪的 ClassCastExceptions 其中说 org.project.Foo 不能分配给 org.project.Foo.

就像偏远岛屿一样,这两个阶级并不知道另一个阶级的存在。想想在不同岛屿上出生并长大的克隆人。从 VM 的角度来看,没有问题,因为 Class 类型的实例像任何其他对象一样处理:可以有几个。你认为其中一些是“相同的”对于虚拟机来说并不重要。

此模式的另一个用途是您可以摆脱以这种方式加载的类:只需确保没有人拥有指向从类加载器加载的类创建的任何对象的指针,然后也忘记类加载器。在下一次运行时 GC, ,该类加载器加载的所有类都会从内存中删除。这允许您“重新加载”应用程序,而无需重新启动整个虚拟机。

我在过去写过几篇关于使用委托后类加载器的博客:

在这种情况下,你不能越过原始来源。如果你 真的 想要里面的涂料, 硬核, , 读 Java 虚拟机规范的相关部分.

java 类加载器的另一个好链接 - Java 类加载器

您需要创建自己的类加载器的情况极为罕见。一般来说,如果您需要的话,您应该已经很好地理解了类加载器的作用。

换句话说,如果您问为什么需要创建自己的类加载器,那么您不需要创建一个;)

话虽这么说,我还看到为处理密码学的应用程序创建了一个类加载器。这样,每次创建 java.netSocket 或某种文件/流对象时,它不会使用 JVM 版本,而是使用它们自己的特殊自定义构建类。这样他们就可以保证所有信息都经过加密并且不存在开发人员错误。

但这并不常见。您可以从事整个 Java 职业生涯,而无需创建自己的自定义类加载器。实际上,如果您需要创建一个,您应该真正询问是否有必要。

为什么开发人员要编写自定义类加载器,为什么不调用 Bootstrap 类加载器来调用您的自定义类?什么情况下需要定义自定义类加载器?

根据应用程序的不同,开发人员可能会覆盖或完全替换类加载机制以满足他们的需求。

例如,我使用了一个应用程序,其类是从 LDAP 加载的:S

其他应用程序需要独立的类管理(就像大多数支持热部署的应用程序服务器)

关于资源,网络上有很多资源,根本无法列出。

一个例子:

Tomcat 使用定制的 WebAppClassloader 来加载和隔离来自不同 Web 应用程序的类/jar。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top