1. Class.forName() 和 loadClass() 加载类的区别
public class Test {
public static class Hello {
static {
System.out.println("hello");
}
}
public static void main(String[] args) {
ClassLoader classLoader = ClassLoader.getSystemClassLoader();
String className = Test.class.getName() + "$Hello";
try {
//Class<?> cls = classLoader.loadClass(className);
Class.forName(className);
System.out.println(classLoader);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
区别: loadClass() 方法加载类不会对其进行初始化,而通过Class.forName() 方法加载类会对其进行初始化。
2. loadClass() 方法(删除了一些代码):
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
synchronized (getClassLoadingLock(name)) {
// 首先,检查类是否已经被加载了
Class<?> c = findLoadedClass(name);
if (c == null) {
// 没被加载,先委派父 ClassLoader 或 Bootstrap ClassLoader 去加载
try {
if (parent != null) {
// 委派父 ClassLoader,resolve 参数固定为 false
c = parent.loadClass(name, false);
} else {
c = findBootstrapClassOrNull(name);
}
} catch (ClassNotFoundException e) {
// 没找到,捕获异常,以便尝试自己价值
}
if (c == null) {
// 自己去加载,findClass 才是当前 ClassLoader 的真正加载方法
c = findClass(name);
}
}
if (resolve) {
// 链接,执行 static 语句块
resolveClass(c);
}
return c;
}
}
参数 resolve 类似 Class.forName 中的参数 initialize,可以看出,其默认值为 false,即使通过自定义 ClassLoader 重写 loadClass,设置 resolve 为 true,它调用父 ClassLoader 的时候,传递的也是固定的 false。
网友评论