线程上下文类装入器与普通类加载器的区别

线程上下文类装入器与普通类加载器的区别

线程的上下文类装入器和普通的类加载器之间有什么区别?

也就是说,如果Thread.currentThread().getContextClassLoader()getClass().getClassLoader()返回不同的类加载器对象,将使用哪一个?


一只甜甜圈
浏览 1163回答 3
3回答

三国纷争

每个类将使用自己的类加载器加载其他类。所以如果ClassA.class参考文献ClassB.class然后ClassB的类加载器的类路径上。ClassA或者它的父母。线程上下文类加载器是当前线程的当前类加载器。中的类创建对象。ClassLoaderC然后传递给ClassLoaderD..在这种情况下,对象需要使用Thread.currentThread().getContextClassLoader()如果它希望加载它自己的类加载器上不可用的资源,则直接加载。

尚方宝剑之说

这并不能回答原来的问题,但因为这个问题的排名很高,而且对任何一个问题都有关联。ContextClassLoader查询,我认为重要的是回答相关的问题,什么时候应该使用上下文类加载器。简短答覆:不要使用上下文类加载器。!但是把它设置为getClass().getClassLoader()当您必须调用缺少ClassLoader参数。当一个类的代码请求加载另一个类时,要使用的正确的类加载器与调用方类相同。(即getClass().getClassLoader())。99.9%的情况是这样的,因为这就是jvm自己所做的。第一次构造新类的实例、调用静态方法或访问静态字段时。当您希望使用反射(例如反序列化或加载可配置的命名类)创建类时,执行反射的库应该总是询问应用程序通过接收ClassLoader作为应用程序的参数。应用程序(它知道所有需要构造的类)应该传递它。getClass().getClassLoader().获得类加载器的任何其他方法都是不正确的。如果库使用诸如Thread.getContextClassLoader(), sun.misc.VM.latestUserDefinedLoader(),或sun.reflect.Reflection.getCallerClass()这是一个由API缺陷引起的错误。基本上,Thread.getContextClassLoader()存在的唯一原因是,无论是谁设计了ObjectInputStreamAPI忘记接受ClassLoader作为一个参数,这个错误至今一直困扰着Java社区。也就是说,许多JDK类使用少数几个黑客中的一个来猜测要使用的类加载器。有些人使用ContextClassLoader(当您在共享线程池上运行不同的应用程序时,或者当您离开ContextClassLoader null),有些人在堆栈中行走(当类的直接调用者本身是一个库时,堆栈就会失败),有些人使用系统类装入器(这很好,只要文档中只使用CLASSPATH)或者引导类加载器,并且有些使用上述技术的不可预测的组合(这只会使事情变得更加混乱)。这导致了大量的哭泣和咬牙切齿。当使用这样的API时,首先,尝试查找接受类加载器作为参数的方法的重载。..如果没有合理的方法,请尝试将ContextClassLoader在API调用之前(然后重新设置它):ClassLoader originalClassLoader = Thread.currentThread().getContextClassLoader();try {     Thread.currentThread().setContextClassLoader(getClass().getClassLoader());     // call some API that uses reflection without taking ClassLoader param} finally {     Thread.currentThread().setContextClassLoader(originalClassLoader);}
打开App,查看更多内容
随时随地看视频慕课网APP