Java有没有办法加载一个已被System ClassLoader加载的类不同的类?

时间:2012-02-09 23:27:06

标签: java system classloader urlclassloader

(可怕的标题,我知道)

解释这个的最好方法是,我需要加载一些将在运行时从URLClassLoader加载的类,这些类引用了已经由System ClassLoader加载的类的实例,并且它们可以&#39因为其他一些问题而被重新加载。

此外,我愿意更改我的代码,以便我可以使用System ClassLoader从类路径中的jar加载类,但我还没有能够做到。

3 个答案:

答案 0 :(得分:3)

没有。每个类加载器都将引导类加载器作为祖先,并且尝试加载已经在类加载器中定义的类将导致使用祖先的版本。这是为了防止java.lang.Object和其他内在函数被重新定义。

来自javadoc for ClassLoader

  

ClassLoader类使用委派模型来搜索类和资源。 ClassLoader的每个实例都有一个关联的父类加载器。 当请求查找类或资源时,ClassLoader实例会在尝试查找类或资源本身之前,将对类或资源的搜索委托给其父类加载器。虚拟机的内置类加载器,称为“引导类加载器”,本身不具有父级,但可以作为ClassLoader实例的父级。

您可以定义一个自定义类加载器,在defineClass不调用它的情况下公开findClass并避免findClass中发生的委派,但我不会依赖defineClass(className, bytes)parent.findClass(className)存在时,1}}按预期在所有JVM上运行。

答案 1 :(得分:1)

是的,您可以定义另一个类加载器并加载该类。

根据规范

“在运行时,类或接口不是由它的名称单独决定,而是由一对决定:它的完全限定名称及其定义的类加载器。每个这样的类或接口属于一个运行时包。类或接口的运行时包由包名称和类或接口的类加载器确定。

答案 2 :(得分:1)

是。但是你需要小心一点,因为默认的父类加载器是系统类加载器,而不是引导类加载器。我建议使用java.net.URLClassLoader.newInstance(myURLs, null)。如果你想成为flash,从系统类加载器中获取父类加载器,那将包括扩展类。

(注意,术语有点扭曲,因为它来自Java2之前,当类路径包含现在的bootclasspath时(安装程序很痛苦)。因此系统类不会被系统类加载器加载。)