Java Class.forName() 与 ClassLoader.loadClass() 的区别

更多 Java 虚拟机方面的文章,请参见文集《Java 虚拟机》


类的显示加载 VS 类的隐式加载

  • 显示加载:
    • 通过 Class c = Class.forName("Student");
    • 通过 ClassLoader 的 loadClass() 方法,例如:
ClassLoader cl = Thread.currentThread().getContextClassLoader();
Class c = cl.loadClass("Student");
  • 隐式加载:通过 new,例如 Student s = new Student("")

Class.forName() VS ClassLoader.loadClass()

关于 Class.forName(),其代码如下:

    public static Class forName(String className)
                throws ClassNotFoundException {
        Class caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

其中 forName0() 方法调用中的参数 true 表示要初始化该类。包括:

  • 执行静态代码块
  • 初始化静态域

关于类的初始化,具体参见 Java 类的加载,链接,初始化

关于 ClassLoader.loadClass(),其代码如下:

    public Class loadClass(String name) throws ClassNotFoundException {
        return loadClass(name, false);
    }

其中 loadClass() 方法调用中的参数 false 表示这个类加载后不需要去链接。

总结

  • Class.forName() 得到的 Class 是已经完成初始化的
  • ClassLoader.loadClass() 得到的 Class 是还没有链接的
  • 一般情况下,这两个方法效果一样,都能装载Class
  • 如果程序依赖于 Class 是否被初始化,就必须用 Class.forName(),例如加载 JDBC 的驱动:
    Class.forName("com.mysql.jdbc.Driver");

你可能感兴趣的:(Java Class.forName() 与 ClassLoader.loadClass() 的区别)