动态加载类时,何时使用
Class.forName("SomeClass");
我应该何时使用
ClassLoader.getSystemClassLoader().loadClass("SomeClass");
或者,他们有两种做同样事情的方法吗?
答案 0 :(得分:145)
他们完全不同!
如Class.forName(String)
的文档中所述,
返回与具有给定字符串名称的类或接口关联的Class对象。调用此方法相当于:
Class.forName(className, true, currentLoader)
(true
这里是指你想要初始化这个类吗?)
另一方面,ClassLoader.loadClass(String)
:
调用此方法相当于调用
loadClass(name, false)
。
(这里,boolean与初始化无关;但是如果你检查loadClass(String,boolean)文档,你会看到它所做的只是加载类,而不是初始化它。)
第一个(Class.forName("SomeClass");
)将:
另一个(ClassLoader.getSystemClassLoader().loadClass("SomeClass");
)将:
假设您正在编写将在Tomcat等容器上执行的Web应用程序。 Tomcat所做的是为每个Web应用程序创建一个类加载器(以便以后可以卸载Web应用程序并释放内存 - 您需要一个专用的类加载器才能使用它!)。在这种情况下,您可以看到两个调用都会产生完全不同的结果!
答案 1 :(得分:7)
Class.forName()
使用调用者的类加载器并初始化类(运行静态intitializers等)。
loadClass
是ClassLoader
方法,因此它使用显式提供的加载器,并且懒惰地初始化类(首次使用时)。
请注意,Class.forName()还需要ClassLoader
。
答案 2 :(得分:1)
他们基本上做同样的事情。使用的ClassLoader可能不同。 Class.forName使用从this.getClass()。getClassLoader()获得的ClassLoader,而您的其他代码指定使用系统类加载器。
在大多数应用程序中,这将是相同的类加载器,但在更复杂的环境中,例如J2EE应用程序或applet,情况可能并非如此。
答案 3 :(得分:0)
ClassLoader是一个抽象类,但是您的应用程序总是由类加载器加载,可能有自定义类加载器,如网络类加载器或任何其他源。
另一方面,Class本身表示类和接口,类Class有一个forName函数,它使用当前运行应用程序的类加载器来加载类。
这是Class.forName的源代码,后者又调用了调用类加载器。
public static Class<?> forName(String className)
throws ClassNotFoundException {
return forName0(className, true, ClassLoader.getCallerClassLoader());
}
http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/ClassLoader.html
http://docs.oracle.com/javase/1.5.0/docs/api/java/lang/Class.html#forName(java.lang.String)
提示:原始类加载器 http://docs.oracle.com/javase/1.4.2/docs/guide/security/spec/security-spec.doc5.html
答案 4 :(得分:0)
Class.forName()
加载并初始化该类。在类加载器子系统中,它执行所有三个阶段,即加载,链接和初始化阶段。
ClassLoader.loadClass()
行为,它会延迟初始化,直到第一次使用该类。在类加载器子系统中,它只执行两个阶段,即加载和链接阶段。
例如:
class MyClass {
static {
System.out.println("static block in MyClass");
}
}
public class TestCase1 {
public static void main(String... args) throws Throwable {
Class.forName("A");
}
} //The above TestCase1 produce output: static block in MyClass
public class TestCase2 {
public static void main(String... args) throws Throwable {
ClassLoader.getSystemClassLoader().loadClass("MyClass");
}
} //The above TestCase2 not produce any output
答案 5 :(得分:-2)
我喜欢java中的类加载...
这实际上取决于运行应用程序的上下文。如果您从Web上下文而不是命令行程序使用它,您将得到不同的结果。
我也遇到了问题,这取决于你的ClassPath看起来是什么以及我期待发生什么。
This JavaWorld文章解释了很多相关内容。