标签:
类加载器负责加载所有的类,系统为所有被载入内存中的类生成一个java.lang.Class实例。一旦一个类被载入JVM中,同一个类就不会被再次载入了。现在的问题是怎么样才算“同一个类”?正如一个对象有一个唯一的标识一样,一个载入JVM的类也有一个唯一的标识。
同理,载入JVM的类也有一个唯一的标识,在java中,一个类用其全限定类名(包括包名和类名)作为标识。但在JVM中,一个类用其全限定类名和其类加载器作为其唯一的标识。因此,如果在pg包中,有一个名为Person的类,被类加载器KlassLoader的实例kl负载加载,则该Person类对应的Class对象在jvm中表示为(Person、pg、kl)。这意味着两个类加载器加载的同名类:(Person、pg、kl)和(Person、pg、kl2)是不同的。它们所加载的类也是完全不同的,互不兼容。
当JVM启动时,会形成由三个类加载器组成的初始类加载器层次结构:
Bootstrap ClassLoader:根类加载器。
Extension ClassLoader:扩展类加载器。
System ClassLoaser:系统类加载器。
Bootstrap ClassLoader,被称为引导(也称为原始或根)类加载器。它负责加载 Java的核心类。在Sun的JVM中,当执行java.exe的命令时使用-Xbootclasspath选项或使用-D选项指定sun.boot.class.path系统属性值可以指定加载附加的类。
根类加载器非常特殊,它并不是java.lang.ClassLoader的子类,而是由JVM自身实现的。
Extension ClassLoader,被称为扩展类加载器,它负责加载JRE的扩展目录(JAVA_HOME/jre/lib/ext或由java.ext.dirs系统属性指定的目录)中的JAR的类包。
System ClassLoaser,被称为系统(也称为应用)类加载器,它负责在JVM启动时,加载来自命令java中的-classpath选项或java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。
JVM的类加载机制主要有如下三种机制:
全盘负责:就是当一个类加载器负载加载某个Class时,该Class锁依赖的和引用的其它Class也将由该类加载器负载载入,除非显式使用另外一个类加载器来载入。
父类委托:就是先让父类加载器试图加载该Class,只有在父类加载器午法加载该类时才尝试从自己的类路径中加载该类。
缓存机制:缓存机制将会保证所有被类加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存中搜寻该Class,只有缓存中不存在该Class对象时,系统才会重读取该类对应的二进制数据,并将其转换成Class对象,并存入cache。这就是为什么修改了Class后,程序必须重新启动JVM,程序所作的修改才会生效的原因
标签:
原文地址:http://www.cnblogs.com/cuike/p/4515404.html