我正在尝试定义自定义的ClassLoader。
public class ExampleLoader extends ClassLoader
{
public Class<?> findClass(String name) throws ClassNotFoundException
{
System.out.println("This never gets printed");
return super.findClass(name);
}
public Class<?> loadClass(String name, boolean b)
throws ClassNotFoundException
{
System.out.println("This never gets printed");
return super.loadClass(name, b);
}
}
当然还有我的代码来测试它:
public class Tester
{
public static void main(String[] args)
{
Thread t = new FooThread();
t.setContextClassLoader(new ExampleLoader());
t.start();
}
}
class FooThread extends Thread
{
public void run()
{
new RandomClass();
}
}
问题是我的线条永远不会被打印出来。显然我错过了什么。
答案 0 :(得分:6)
这与bug 4868493有关。这是一个相关的引用:
不幸的是
getContextClassLoader
和setContextClassLoader
的文档ClassLoader
可能导致人们得出结论 提交者的代码应该按预期工作。但是,类加载中有一个基本规则 - 没有类可以 自动加载一个“下游”的类,即不能 由该类
ClassLoaders
或其祖先之一直接加载Thread.getContextClassLoader
。这在许多地方都有描述。例如,冥想 白皮书在这里: http://www.javageeks.com/Papers/ClassForName/index.html 获得启蒙。
关键点似乎是没有使用上下文类加载器 由Java语言自动完成。这只是一个传统的地方 存储上下文类加载器,以便其他类可以使用它 3-argument form of
Class.forName
强>
Thread.setContextClassLoader
和new RandomClass()
的规范 应该澄清,“上下文类加载器”的含义应该 澄清一下。重新归类为doc bug。
该规范尚未澄清。
要让它按照您最初的要求工作,请将<{1}}替换为
Class.forName(RandomClass.class.getName(),
true,
getContextClassLoader()).newInstance();
这反映了以下内容:
This never gets printed
答案 1 :(得分:0)
通常,JVM中的所有类加载器都按层次结构组织,以便每个类加载器(引导整个JVM的原始类加载器除外)都具有单个父级。当被要求加载一个类时,每个兼容的类加载器都应该首先将加载委托给它的父级,并且只有在父级失败时才尝试定义该类。
在你的情况下也会发生同样的事情。要加载“RandomClass”,ContextClassLoader委托给它的父级,依此类推。其中一个父类加载器能够加载“RandomClass”(RandomClass在父类的路径中)。由于这个原因,你的SOP没有出现。
参考以下文章有点旧但很好:
http://www.javaworld.com/javaworld/javaqa/2003-06/01-qa-0606-load.html?page=1