类加载器
类加载器主要负责将.class文件加载到内存中,并为值生成对应的java.lang.Class对象。尽管在Java开发红程序员无须过分关心类加载机制,但应该了解其工作机制。
一旦一个类被载入JVM中,同一个类就不会被再次载入了,载入JVM的类有一个唯一的标识,在Java中,一个类用其全限定类名(包括包名和类名)作为标识。
但在JVM中,一个类用其全限定类名和其类的加载器作为唯一的标识。比如:类名是Person,包名是:类加载器ClassLoader的实例为k1负责加载。这Person类的Class对象在JVM中表示为(Person、pg、k1)。
当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构:
(1)Bootstrap ClassLoader:根类加载器。
(2)Extension ClassLoader:扩展类加载器。
(3)System ClassLoader:系统类加载器。
Bootstrap ClassLoader被称为引导(也称为原始或根)类加载器。它负责加载Java的核心类。根类加载器非常特殊,它并不是java.lang.ClassLoader的子类,而是有Java虚拟机自身实现的。
Extension ClassLoader被称为扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或者由java.ext.dirs系统属性指定的目录)中JAR的类包。通过这种方式,我们就可以为Java扩展核心类以外的新功能,只要我们把自己开发的类打包成JAR文件,然后放入JAVA_HOME/jre/lib/ext路径即可。
System ClassLoader被称为系统(也称为应用)类加载器,它负责在JVM启动时,加载来自命令java中的-classpath选项或java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。
程序可以通过ClassLoader的静态方法getSystemClassLoader()获取该类加载器。如果没有特别指定,则用户自定义的类加载器都以该加载器作为它的父加载器。
Java虚拟机的类加载机制主要有如下三种机制:
(1)全盘负责:所谓全盘负责,就是说当一个类加载器负责加载某个Class的时候,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示的使用其他类加载器。
(2)父类委托:所谓父类委托则是先让parent类加载器试图加载该Class,只有在父类加载器无法加载个该类时才尝试使用自己的类路径加载该类。
(3)缓存机制:缓存机制将会保证所有被加载过的Class都会被缓存,当程序中需要使用某个Calss时,类加载器先从缓存中搜索该Class,只有当缓存中不存在该Class对象时,系统才会从新读取该类对应的二进制数据,并将其转换为Class对象,并存入缓存中。这就是为什么我们修改了Class后,程序必须重新启动JVM,程序所作的修改才会生效的原因。
希望对你有所帮助。 |