05.类的加载器一(详解)

来源:互联网 发布:贵州大数据局官网 编辑:程序博客网 时间:2024/06/14 07:29

类加载器用来把类加载到java虚拟机中, 从jdk1.2开始,类的加载过程采用父亲委托机制。这种机制能更好的保证java平台的安全。此委托机制中,除了java虚拟机自带的根类加载器外,其余的类加载器有且只有一个父加载器。当java程序请求加载器loader1加载sample类时,loader1首先委托自己的父类加载器去加载sample类,若父类加载器能加载,则由父类加载器完成加载任务,否则由加载器loader本身加载sample类。

java虚拟机自带了以下几种加载器:
1.根(bootstrap)类加载器:该加载器没有父类加载器,它负责加载虚拟机的核心类库,如java.lang.*等,**图1中**就能看出java.lang.Object 是由根类加载器加载的。根类加载器从系统属性sun.boot.class.path所指定的目录中加载类库。根类加载器的实现依赖于底层操作系统,属于虚拟机实现的一部分,他并没有继承java.lang.ClassLoader类。
2.扩展(Extension)类加载器:他的父类加载器为根类加载器。它从java.ext.dirs系统属性所指定的目录中加载类库,或者从jdk的安装目录的jre\lib\ext子目录(扩展目录)下加载类库,如果把用户创建的jar文件放到这个目录,也会自动由扩展类加载器加载。扩展类加载器是纯java类,是java.lang.ClassLoader类的子类。
3.系统(System)类加载器:也叫应用类加载器,他的父类加载器为扩展类加载器。他从环境变量classpath或者系统属性java.class.path所指定的目录加载类。他是用户自定义的类的加载器的默认父加载器。系统类加载器是纯java类,是java.lang.ClassLoader类的子类。
图1:
图1:
除了上述虚拟机自带的几个加载器之外,用户还可以定制自己的类加载器。java提供了抽象类java.lang.ClassLoader,所有用户自定义的类加载器,都应该继承ClassLoader类。
图2:
图2:

在父亲委托机制中,各个加载器按照父子关系形成了树形结构,除根类加载器之外,其余的类加载器都有且只有一个父类加载器。
图3:
图3:
如果有父类加载器,就交给父类加载器加载,如果父类加载器加载不了,那就由当前加载器加载。
图4:
图4


若一个类加载器能成功加载sample类,那么这个类加载器被称为定义类加载器,定义类加载器以及其所有子类加载器都被称之为初始类加载器
例如:
loader1实际加载了sample类,则loader1为sample类的定义类加载器,loader1和loader2为sample类的初始类加载器。


当生成一个自定义的类加载器实例时,如果没有指定他的父类加载器,那么系统类加载器就将成为该类加载器的父类加载器。

ClassLoader loader1 = new MyClassLoader();//参数loader1将作为loader2的父类加载器ClassLoader loader2 = new MyClassLoader(loader1);![这里写图片描述](http://img.blog.csdn.net/20171009155536913?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvd2FlaTA4/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

父亲委托机制的优点是能够提高软件系统的安全性,因为在此机制下,用户自定义的类加载器不可能加载应该又父类加载器加载的可靠类,从而防止不可靠甚至恶意代码代替父类加载器加载可靠代码。例如,java.lang.Object总是由根类加载器加载,其他任何用户自定义的类加载器都不可能加载含有恶意代码的java.lang.Object类。

原创粉丝点击