如何在JVM中使用classloader加载一次类?

时间:2017-05-03 01:04:17

标签: java jvm classloader

我在Java采访中被问到过。我们知道,由于父代理模型,Java类加载器只会加载一次类。所以我的答案是使用自定义类加载器来加载它。是对的吗?如何回答这个问题?

1 个答案:

答案 0 :(得分:2)

这取决于。限定名称以java.开头的类只能由引导加载程序加载,因此根本不会第二次加载。引导加载程序加载的所有其他类只能由不遵循父委托模型的自定义类加载器实现加载,因为引导加载程序是所有加载程序的父项。

对于由ClassLoader实例加载的所有其他类,可以按照父委托模型构建标准类加载器,但不能将该加载器作为父类。但是,当然,您也可以使用自定义加载程序来加载它们,而不是遵循委托模型。选择可能取决于您希望如何处理该类引用的其他类,这些类最初由同一个加载器加载。您也可以重新加载它们,创建该环境的完整副本或尝试将其加载重定向到原始加载器,如果存在反向引用,则会产生问题。

以下代码示例演示了该方法:

public class ReloadMySelf {
    public static void main(String[] args) throws IOException, ClassNotFoundException {
        final Class<?> o = ReloadMySelf.class;
        URL loc = o.getProtectionDomain().getCodeSource().getLocation();
        ClassLoader parent = o.getClassLoader().getParent();
        try(URLClassLoader cl = new URLClassLoader(new URL[]{loc}, parent)) {
           Class<?> duplicate = cl.loadClass(o.getName());
           System.out.println("original: "+o+" ("+o.getClassLoader()+')');
           System.out.println("duplicate: "+duplicate+" ("+duplicate.getClassLoader()+')');
        }
    }
}