他们完全不同!
如文档中所述Class.forName(String) http://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName%28java.lang.String%29,
返回与具有给定字符串名称的类或接口关联的 Class 对象。调用该方法相当于:Class.forName(className, true, currentLoader)
(true
这里指的是你想初始化这个类吗?)
另一方面,ClassLoader.loadClass(String) http://docs.oracle.com/javase/7/docs/api/java/lang/ClassLoader.html#loadClass%28java.lang.String%29:
调用该方法相当于调用loadClass(name, false)
.
(这里,布尔值与初始化无关;但是如果您检查 loadClass(String, boolean) 文档,您会发现它所做的只是加载类,而不是初始化它)。
第一个 (Class.forName("SomeClass");
) will:
- 使用加载调用此代码的类的类加载器
- 初始化类(即,将运行所有静态初始化程序)
另一个 (ClassLoader.getSystemClassLoader().loadClass("SomeClass");
) will:
- 使用“系统”类加载器(这是可重写的 https://stackoverflow.com/q/5380275/632951)
- 不初始化该类(例如,如果您使用它来加载 JDBC 驱动程序,它将不会注册,并且您将无法使用 JDBC!)
假设您正在编写一个将在 Tomcat 等容器上执行的 Web 应用程序。 Tomcat 所做的是为每个 Web 应用程序创建一个类加载器(以便稍后可以卸载 Web 应用程序并释放内存——您需要一个专用的类加载器才能工作!)。在这种情况下,您可以看到两个调用都会产生完全不同的结果!
有关类加载和初始化的更详细(和权威)信息,请查看部分12.2 http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.2 and 12.4 http://docs.oracle.com/javase/specs/jls/se7/html/jls-12.html#jls-12.4Java 语言规范的最新(第 3 版)版本。