这里讨论的
Class.forName
是Class
类的方法public static Class<?> forName(String className) throws ClassNotFoundException
这里讨论的
ClassLoader.loadClass
是ClassLoader
类的方法public Class<?> loadClass(String name) throws ClassNotFoundException
ClassLoader在加载类时的概念区分
Class.forName
和ClassLoader.loadClass
都可以用来进行类型加载,而在Java进行类型加载的时刻,一般会有多个ClassLoader可以使用,并可以使用多种方式进行类型加载。
比如如下代码:
class A {
public void m() {
A.class.getClassLoader().loadClass(“B”);
}
}
在A.class.getClassLoader().loadClass(“B”);
代码执行B的加载过程时,一般会有三个概念上的ClassLoader提供使用。
CurrentClassLoader,称之为当前类加载器,简称CCL,在代码中对应的就是类型A的类加载器。
SpecificClassLoader,称之为指定类加载器,简称SCL,在代码中对应的是 A.class.getClassLoader()
,如果使用任意的ClassLoader进行加载,这个ClassLoader都可以称之为SCL。
ThreadContextClassLoader,称之为线程上下文类加载器,简称TCCL,每个线程都会拥有一个ClassLoader引用,而且可以通过Thread.currentThread().setContextClassLoader(ClassLoader classLoader)
进行切换。
SCL和TCCL可以理解为在代码中使用ClassLoader的引用进行类加载,而CCL却无法获取到其引用,虽然在代码中CCL == A.class.getClassLoader() == SCL。
CCL的加载过程是由JVM运行时来控制的,是无法通过Java编程来更改的。
这里提到了CCL、SCL和TCCL,那么和Class.forName
以及ClassLoader.loadClass
有什么关系呢?因为我们在分析Class.forName
和ClassLoader.loadClass
时将会涉及到这些ClassLoader。
Class.forName与SystemDictionary
Class.forName
是根据给定的类型全名从CCL中加载指定的类型。
实现代码:
@CallerSensitive