Thread.currentThread()类加载器和普通类加载器的区别

15

你能告诉我Thread.currentThread().getContextClassLoader()TestServlet.class.getClassLoader()之间的区别吗?请不要将其标记为重复,并请解释并提供使用这些内容的示例

Java文件:

package com.jar.test;

public class TestServlet {
    public static void main(String args[]) {    
        ClassLoader cls = TestServlet.class.getClassLoader().loadClass(
                "com.jar.test.TestServlet");
        ClassLoader cls = Thread.currentThread().getContextClassLoader()
                .loadClass("com.jar.test.TestServlet");
    }
}

2
实际上这是一个重复问题 - nandsito
1
如果您知道这是一个重复的问题,请不要将其标记为重复。请分享您的研究,链接到重复问题页面,并解释它与您的问题有何不同。同时,我已将此标记为重复问题...(顺便说一句,给出“不要标记…”这样的命令可能被认为是粗鲁的。) - Martin Nyolt
2个回答

11

Thread.currentThread().getContextClassLoader()

Thread.currentThread().getContextClassLoader() 返回当前线程的上下文ClassLoader。上下文ClassLoader是由创建该线程的代码提供的,用于在该线程中运行时加载类和资源。如果未设置,则默认为父级线程的上下文ClassLoader。原始线程的上下文ClassLoader通常设置为用于加载应用程序的类加载器。

Class#getClassLoader()

Class#getClassLoader() 返回该类的ClassLoader。某些实现可能使用null来表示引导类加载器。如果该类是由引导类加载器加载的,在这些实现中,此方法将返回null


简要概述:

Thread.currentThread().getContextClassLoader() 返回已通过setContextClassLoader(ClassLoader cl)方法设置的线程上下文ClassLoader。假设您有一个具有层次结构的ClassLoader(例如应用程序服务器)的复杂java应用程序,并且希望当前线程从此层次结构中的一个特定的ClassLoader加载类或资源,您可以通过将线程的上下文ClassLoader设置为该特定的ClassLoader来实现。

Class#getClassLoader() 简单地返回加载此Class实例的ClassLoader


7

Thread.currentThread().getContextClassLoader()

这是当前线程的类加载器,不依赖于调用它的类。

TestServlet.class.getClassLoader()

这是加载TestServlet类的类加载器。

请解释并提供使用这些内容的示例

假设您有Thread1由ClassLoader1拥有和Thread2由ClassLoader2拥有。您可能会在Thread2(由ClassLoader2)上加载TestServlet类,然后将其传递给Thread1。此时,如果TestServlet需要加载由ClassLoader1拥有的类,则需要使用Thread.currentThread().getContextClassLoader(),因为它自己的类加载器是ClassLoader2而不是ClassLoader1。


感谢大家,如果可能的话,请提供一些示例代码,以便我更好地理解。 - sidhartha pani
1
这应该是被接受的答案,因为它解释了在某些情况下为什么必须使用其中之一。 - Marco Sulla

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接