3
回答
请问Thread.currentThread().setContextClassLoader的用途?
注册华为云得mate10,2.9折抢先购!>>>   
public static void main(String[] args) throws Exception {
Thread.currentThread().setContextClassLoader(new FileSystemClassLoader("D:\\123"));
System.out.println(Thread.currentThread().getContextClassLoader()); 
System.out.println(PrintMessage.class.getClassLoader());

}

PrintMessage 是main类的一个同包的类,我设置了classloader为自定义类加载器,去D:\\123目录下加载这个类,但是为什么实际上他还是用系统自带的AppClassLoader加载了呢。 那设置当前线程的类加载器到底有什么用呢。  

初学类加载方面的知识,请高手帮忙解答下,谢谢啦。

举报
a12939026
发帖于4年前 3回/4K+阅
共有3个答案 最后回答: 2年前

引用来自“huaye2007”的评论

你哪个地方有去loadClass?只看到你设置类加载器,并没有看到使用类加载器去加载一个类。

谢谢回答。 其实这个就是我比较疑惑的。 

显式地loadclass 确实会用到自定义的加载器,但是那样不用setcontextloader呀。。

系统会自动调用classlaoder,难道不是调用我设置的么。 

这个就是我不明白的地方~~

--- 共有 2 条评论 ---
a12939026回复 @huaye2007 : 不行哦。 我试过。 这样就直接classnotfoundexception了。 4年前 回复
星爷Thread.currentThread().setContextClassLoader 虽然你设置了这个,但是父类加载器AppClassLoader还是在之前的classpath可以找到你这个类,所以AppClassLoader就加载了。我是这样理解的。你可以把一个类编译好放在d:123文件夹下 但main类包下面没有这个类。这个时候就会调用自定义的类加载器。 4年前 回复
之所以要有Thread.currentThread().setContextClassLoader,是为了打破双亲委托机制的,这个一般用在父类加载器加载的类要调用子加载器加载的类(这个如果使用双亲委托是做不到的),因为默认JVM使用的是父加载优先加载,你这里虽然调用了Thread.currentThread().setContextClassLoader,但是加载你的PrintMessage类的类加载器是JVM自带的双亲委托方式加载,也就是 App ClassLoader加载,而App ClassLoder并没有显示的调用 Thread.currentThread().getContextClassLoader 去加载PrintMessage,所以你这样设置并没有用。你可以看下Java的SPI机制,具体看 ServiceLoader类。
顶部