2016-02-21 48 views
3

在我的理解中,所有java类都被动态加载到内存中,即当第一次看到一个CLASS符号时,它将其内容加载到内存中。正确定义java动态类加载

在java中,我们常说,我们正在做以下时,JVM加载类动态 :

(1)

Class aClass = classLoader.loadClass("com.stackoverflow.MyClass"); 

但是,从我之前所说的,对我来说,似乎总是一样的东西。 我的意思是不需要更多的步骤来加载一个类,使用片段(1),比第一次碰到一个CLASS符号时加载类时所需的步骤。

我错了吗? 一直以来他们是两个不同的概念吗? 谢谢

回答

4

嘛,他们不是完全相同相同,但总体而言,你说得对,classLoader.loadClass("com.stackoverflow.MyClass")基本上给出了相同的效果,只是指com.stackoverflow.MyClass类里面。

classLoader.loadClassClass.forName等的主要动力是,他们让你加载类是通过硬编码字符串命名。例如,类名可能出现在配置文件中。 (The Spring framework,例如,做尽可能多的这是任何人所能想。)

其次,这些方法也提出在该类无法加载的情况下,更可操作的例外。例如,SLF4J提供了其他库可以编译的单个API JAR文件,但提供了几种不同的实现JAR文件,最终应用程序可以使用它们进行部署(一个委托给Log4j,一个委托给java.util.logging.Logger等)。在运行时,SLF4J会尝试通过动态加载org.slf4j.impl.StaticLoggerBinder来查找已部署的实现,但如果找不到它,它只会打印警告(并且默认为不执行操作)而不是炸毁。如果SLF4J API JAR文件中的类静态取决于org.slf4j.impl.StaticLoggerBinder类,则此方法无效。

2

我认为classLoader.loadClass("com.stackoverflow.MyClass")确实是告诉编译器明确加载指定的类为当前classLoader。在正常情况下,类已经在执行程序的类路径中,你的假设是正确的,它已经默认加载了。

但是,可能会出现需要从其他来源(如网络或二进制流)中读取类的情况。在这种情况下,默认加载行为可能不会读取这些类,loadClass()将指示编译器明确加载它们。

欲了解更多详细信息,您可以参考ClassLoader javadoc