Java类加载器

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

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

    提前致谢。

我找到了以下有效创建自定义类加载器的原因:

  1. 您希望从非常规源加载类(例如,一个类的字节码存储在数据库中,跨网络或由pidgeons – MessengerPidgeonClassLoader 作为0和1进行 )。 对于此类情况,API中已存在一些ClassLoader实现,例如URLClassLoader 。

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

  3. 您需要对字节码进行一些修改。 也许字节码是加密的,你会在运行中解密它( 不是它有帮助,真的,但已经尝试过 )。 也许你想要“修补”动态加载的类(一个JDO字节码增强)。

如果需要从内存中卸载类,或者加载类而不是在运行时更改其定义,则需要使用与System Classloader不同的类加载器。 典型的情况是,例如,从XML文件动态生成类的应用程序,然后尝试重新加载此类。 一旦类在System Classloader中,就无法卸载它并拥有新的定义。

类加载器的一个常见用途是隔离JAR。 如果你有一个使用插件的应用程序( Eclipse , Maven 2 ),那么你可以遇到这种情况:插件X需要jar A版本1.0,而插件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时 ,此类加载器加载的所有类都将从内存中删除。 这使您可以“重新加载”应用程序,而无需重新启动整个VM。

我在很久以前写过一些关于使用授权后类加载器的博客:

  • 编写一个授权后的类加载器
  • 两个类加载器的故事

在这种情况下,你无法通过原始资源。 如果你真的想要内部涂料, 硬核 ,请阅读Java虚拟机规范的相关部分 。

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

您需要创建自己的ClassLoader是极其罕见的。 而且如果你需要的话,你应该已经对ClassLoader的作用有了很好的理解。

换句话说,如果你问为什么你需要创建自己的ClassLoader,那么你不需要创建一个;)

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

但这并不常见。 您无需创建自己的自定义ClassLoader即可完成整个Java职业生涯。 实际上,如果你需要创建一个,你应该真的问是否有必要。

为什么开发人员编写Custom类加载器,为什么不调用Bootstrap类加载器来调用自定义类呢? 有什么需要定义自定义类加载器?

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

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

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

关于资源,网络中有TONS,根本无法列出。

一个例子:

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