(可怕的标题,我知道)
解释这个的最好方法是,我需要加载一些将在运行时从URLClassLoader加载的类,这些类引用了已经由System ClassLoader加载的类的实例,并且它们可以&#39因为其他一些问题而被重新加载。
此外,我愿意更改我的代码,以便我可以使用System ClassLoader从类路径中的jar加载类,但我还没有能够做到。
答案 0 :(得分:3)
没有。每个类加载器都将引导类加载器作为祖先,并且尝试加载已经在类加载器中定义的类将导致使用祖先的版本。这是为了防止java.lang.Object
和其他内在函数被重新定义。
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时(安装程序很痛苦)。因此系统类不会被系统类加载器加载。)