有没有人能指点我一个好的资源或者解释一下类加载器背后的概念?我在类加载器方面找到了以下的资源http://www.onjava.com/lpt/a/5586,但还是没有帮助。以下问题可能看起来很傻,但尝试回答它们总是让我感到困惑。
为什么开发人员要编写自定义类加载器?为什么不调用启动类加载器来调用您的自定义类?定义自定义类加载器的必要性是什么?
为什么有这么多种类的类加载器?例如:引导、通用、Catalina 类加载器等。
先谢谢了。
有没有人能指点我一个好的资源或者解释一下类加载器背后的概念?我在类加载器方面找到了以下的资源http://www.onjava.com/lpt/a/5586,但还是没有帮助。以下问题可能看起来很傻,但尝试回答它们总是让我感到困惑。
为什么开发人员要编写自定义类加载器?为什么不调用启动类加载器来调用您的自定义类?定义自定义类加载器的必要性是什么?
为什么有这么多种类的类加载器?例如:引导、通用、Catalina 类加载器等。
先谢谢了。
你想从非传统来源加载类(例如,一个类的字节码存储在数据库中、通过网络或由鸽子携带为0和1 - MessengerPidgeonClassLoader)。已经有一些API中的ClassLoader实现用于这种情况,例如URLClassLoader。
您需要定义不同的层次结构来加载类。ClassLoader的默认实现首先将搜索委托给父级,然后尝试自己加载类。也许您想要一个不同的层次结构。这就是OSGI和Eclipse拥有自己的ClassLoader的原因,因为Manifest .MF文件定义了各种奇怪的层次结构路径(例如buddy-classloading)。所有Eclipse类加载器都实现BundleClassLoader接口,并具有一些额外的代码以在Eclipse插件中查找资源。
您需要对字节码进行一些修改。也许字节码被加密,你将在运行时解密它(虽然这并没有什么帮助,但已经尝试过)。也许你想“修补”在运行时加载的类(就像JDO字节码增强一样)。
如果需要从内存中卸载类或加载可能在运行时更改其定义的类,则需要使用不同于系统类加载器的类加载器。典型情况是应用程序从XML文件动态生成类,然后尝试重新加载此类。一旦类位于系统类加载器中,就无法卸载它并获得新的定义。
cl1.getName().equals(cl2.getName())
是true
,但 cl1.equals(cl2)
不是。这意味着cl1的实例不能赋值给cl2的实例。这可能导致奇怪的ClassCastExceptions
,其显示无法将org.project.Foo
分配给org.project.Foo
。你很少需要创建自己的ClassLoader。一般来说,如果你需要创建一个,你应该已经非常了解ClassLoader的作用。
换句话说,如果你问为什么需要创建自己的ClassLoader,那么你就不需要创建一个;)
话虽如此,我也见过为处理加密技术的应用程序创建ClassLoader的情况。这样,每次创建java.netSocket或某种文件/流对象时,它们会使用自己特殊构建的类,而不是使用JVM版本。这样他们可以保证所有信息都被加密,没有开发人员错误。
但这并不常见。你可以在整个Java职业生涯中从未需要创建自己的自定义ClassLoader。实际上,如果你需要创建一个,你应该真正考虑是否有必要。