类加载 Class.forName() 和 loadClass() 详解

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。

你可能感兴趣的:(类加载 Class.forName() 和 loadClass() 详解)