什么是Java ClassLoader?

在几个简单的句子中,什么是Java ClassLoader,什么时候使用它,为什么?

好的,我读了一篇维基文章。 ClassLoader加载类。好。因此,如果我包括jar文件和导入,一个ClassLoader做的工作。

为什么我应该打扰这个ClassLoader?我从来没有使用它,不知道它存在。

问题是,为什么ClassLoader类存在?而且,你如何在实践中使用它? (情况存在,我知道。)

最佳答案
从这个漂亮的tutorial从太阳:

动机

以静态编译的编程语言(例如C和C)编写的应用程序被编译为本机的机器特定指令并保存为可执行文件。将代码组合为可执行本机代码的过程称为链接 – 将单独编译的代码与共享库代码合并,以创建可执行应用程序。这在动态编译的编程语言如Java中是不同的。在Java中,由Java编译器生成的.class文件保持原样,直到加载到Java虚拟机(JVM) – 换句话说,链接过程由JVM在运行时执行。类根据需要加载到JVM中。当一个加载的类依赖另一个类,那么该类也被加载。

当启动Java应用程序时,运行的第一个类(或者进入应用程序的入口点)是一个带有public static void方法的函数main()。这个类通常引用其他类,并且所有尝试加载引用的类都是由类加载器执行的。

为了得到这种递归类加载的感觉以及一般的类加载思想,考虑下面的简单类:

public class HelloApp {
   public static void main(String argv[]) {
      System.out.println("Aloha! Hello and Bye");
   }
}

如果运行此类,指定-verbose:class命令行选项,以便打印正在加载的类,您将得到如下所示的输出。注意,这只是一个部分输出,因为列表太长,不能在这里显示。

prmpt>java -verbose:class HelloApp



[Opened C:\Program Files\Java\jre1.5.0\lib\rt.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jsse.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\jce.jar]
[Opened C:\Program Files\Java\jre1.5.0\lib\charsets.jar]
[Loaded java.lang.Object from shared objects file]
[Loaded java.io.Serializable from shared objects file]
[Loaded java.lang.Comparable from shared objects file]
[Loaded java.lang.CharSequence from shared objects file]
[Loaded java.lang.String from shared objects file]
[Loaded java.lang.reflect.GenericDeclaration from shared objects file]
[Loaded java.lang.reflect.Type from shared objects file]
[Loaded java.lang.reflect.AnnotatedElement from shared objects file]
[Loaded java.lang.Class from shared objects file]
[Loaded java.lang.Cloneable from shared objects file]
[Loaded java.lang.ClassLoader from shared objects file]
[Loaded java.lang.System from shared objects file]
[Loaded java.lang.Throwable from shared objects file]
.
.
.
[Loaded java.security.BasicPermissionCollection from shared objects file]
[Loaded java.security.Principal from shared objects file]
[Loaded java.security.cert.Certificate from shared objects file]
[Loaded HelloApp from file:/C:/classes/]
Aloha! Hello and Bye
[Loaded java.lang.Shutdown from shared objects file]
[Loaded java.lang.Shutdown$Lock from shared objects file]

如您所见,应用程序类(HelloApp)所需的Java运行时类首先加载。

Java 2平台中的类装载器

Java编程语言不断发展,使应用程序开发人员的生活变得更轻松。这通过提供简化您的生活的API,通过允许您专注于业务逻辑而不是基本机制的实现细节来完成。这通过J2SE 1.5最近更改为J2SE 5.0以反映Java平台的成熟度而显而易见。

从JDK 1.2开始,内置在JVM中的引导类加载器负责加载Java运行时的类。此类加载器仅加载在引导类路径中找到的类,并且由于这些类是受信任的类,因此不对不受信任的类执行验证过程。除了引导类加载器之外,JVM还有一个扩展类加载器,负责从标准扩展API加载类,以及一个系统类加载器,从一般类路径和应用程序类加载类。

由于有多个类加载器,它们表示在一个树中,其根是引导类加载器。每个类加载器都有对其父类加载器的引用。当一个类加载器被要求加载一个类时,它在尝试加载该项本身之前查询它的父类加载器。父母继而咨询其父母,等等。因此,只有所有的祖先类加载器都无法找到当前类加载器涉及的类。换句话说,使用委托模型。

java.lang.ClassLoader类

java.lang.ClassLoader是一个抽象类,可以由需要扩展JVM动态加载类的方式的应用程序进行子类化。 java.lang.ClassLoader(及其子类)中的构造方法允许您在实例化新的类加载器时指定父对象。如果没有明确指定父级,则虚拟机的系统类装入器将被指定为默认父级。换句话说,ClassLoader类使用委托模型来搜索类和资源。因此,每个ClassLoader实例都有一个相关的父类加载器,因此当被请求查找一个类或资源时,在尝试找到类或资源本身之前,任务被委托给它的父类加载器。 ClassLoader的loadClass()方法在调用以加载类时按顺序执行以下任务:

如果一个类已经被加载,它会返回它。
否则,它将对新类的搜索委托给父类加载器。
如果父类加载器没有找到类,loadClass()调用方法findClass()来查找和加载类。
如果父类加载器找不到类,finalClass()方法将搜索当前类加载器中的类。

还有更多的原始文章,它还显示了如何实现自己的网络类加载器,这回答了你的问题,为什么(以及如何)。参见API docs

转载注明原文:什么是Java ClassLoader? - 代码日志