黑马程序员--05.类加载器--01【类加载器基本知识】【类加载器的委托机制】

来源:互联网 发布:怎么查淘宝账号权重 编辑:程序博客网 时间:2024/05/29 19:59

类加载器--1

类加载器基本知识        类加载器的委托机制

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

1.    类加载器的基本知识

1). 系统默认类加载器的应用场景

(1). 常见的一段代码

public static void main(String[] args) {    System.out.println("Hello World!");}

(2). 分析

[1]. Java中用到了System这个类,这样JVM首先把System.class这个字节码文件加载到内存中来。

[2]. JVM首先把字节码文件从硬盘上加载进来,并做一些处理之后,这些硬盘的字节码文件就变成了内存字节码

这里加载的具体工作是由类加载器ClassLoader来执行的。

2). 系统默认类加载器

(1). 3个系统的默认类加载器

[1]. Java中默认的类加载器有3BootstrapExtClassLoaderAppClassLoader

[2]. 类加载器作用用来加载其他Java

[3]. 类加载器底层

{1}. 这3系统默认的类加载器中名字后面带有ClassLoader的话,都是Java语言编写的Java。这样AppClassLoaderExtClassLoader都是普通的Java

{2}. Boostrap本身是C++编写的代码不是Java语言编写的Java

(2). Bootstrap类加载器基本知识

[1]. Bootstrap所属

{1}.Bootstrap类加载器不是Java类,不需要被别的类加载JVM内核的一部分

{2}.Bootstrap类加载器也叫JVM的内嵌类加载器

[2]. Bootstrap类加载器启动时机

{1}. 由于Bootstrap类加载器JVM内核的一部分,所以Bootstrap类加载器随着JVM的启动而启动

[3]. Bootstrap类加载器作用

主要用来加载其他的系统默认的类加载器ExtClassLoaderAppClassLoader类加载器

3). 类加载器的继承关系及管辖范围

(1). 类加载器的继承体系图


[1]. Bootstrap类加载器

{1}. 名称引导类加载器

{2}. 位置:最高父级类加载器

{3}. 管辖范围:负责加载Java的核心类库中的

{3}1. Java核心类库在文件系统中的位置

被打包到Java的jdk安装目录子目录jre/lib/rt.jar(rtruntime的缩写)

注意】包括ExtClassLoader和AppClassLoader类

[2]. ExtClassLoader类加载器

{1}. 名称扩展类加载器

{2}. 位置:Bootstrap类的直接子类

{3}. 管辖范围:负责加载打包到Java的jdk安装目录子目录jre/ext/下面所有的jar包

[3]. AppClassLoader类加载器

{1}. 名称系统类加载器

{2}. 位置:ExtClassLoader类的直接子类

{3}. 管辖范围:负责加载系统环境变量ClASSPATH指定目录中所有的JAR

(2).测试ExtClassLoader、AppClassLoader和Bootstrap的继承关系

[1]. 测试代码

public class Test {    public static void main(String[] args) {       ClassLoaderclassLoader =Test.class.getClassLoader();             while(classLoader !=null){           System.out.println(classLoader.getClass().getName());           classLoader=classLoader.getParent();       }       System.out.println(classLoader);    }}

【注意】ExtClassLoaderAppClassLoader类加载器也是Java类,所以一定有对应的Class对象。所以ClassLoader类的实例还是可以继续

[2]. 打印结果


【注意】注意到打印ExtClassLoaderAppClassLoader打印出的类名是Launcher$AppClassLoaderLauncher$ExtClassLoader这说明AppClassLoaderExtClassLoderLauncher内部类!!!!

[3]. 结果分析

{1}. Test.java 所处的位置:MyEclipse下面工程名ClassLoader的默认包下,如图


{2}. 前面的章节已经分析过,MyEclipse的具体工程中的.classpath文件会在执行这个工程的某个java文件的时候,通过这个文件把这个工程所在的目录临时添加到CLASSPATH变量。这样名叫ClassLoader工程下的Test.java文件对应的字节码实际上是位于AppClassLoader管辖的范围内

{3}. 这样,就可以知道ClassLoaderclassLoader =Test.class.getClassLoader();程序中用到了Test这个类的字节码。JVM指定AppClassLoader去加载的这个Test.java。所以,classLoader此时指向的是AppClassLoader这个类加载器的实例。

       此时JVM继续执行程序,while条件满足,执行循环体

System.out.println(classLoader.getClass().getName());

classLoader =classLoader.getParent();

打印出AppClassLoader的全类名之后,再一次将classLoader指向了AppClassLoader的直接父类实例。由继承关系图可知,此时classLoader指向了ExtClassLoader这个类的实例。

此时循环条件任然满足,继续执行循环体,打印出ExtClassLoader的全类名。又一次让classLoader指向了ExtClassLoader实例的直接父类实例。但是由于Bootstrap不是Java类,所以不可能有Java对象。所以这次classLoader指向了null。此时循环条件不满足,循环体执行结束。最后打印出null。

2.    类加载器的委托机制

1). 委托机制的应用场景

Java的jdk安装目录子目录 jre/ext/中的某个jar包中某个class文件( ExtClassLoader的加载范围) 和CLASSPATH指定目录下的某个class文件(AppClassLoader的加载范围)同名的时候JVM会指派哪一个类加载器进行加载呢

2). 类加载器的委托机制

类加载器委托机制简述

[1]. 当需要某个类加载器加载指定的类的时候,不是立刻自己的管辖范围去加载指定的字节码文件,而是将这个指定的类传递给父类,由父类尝试去到自己的加载范围去加载这个类。就这样,一级级地向上递推类加载器的最高父类JVM的内嵌类加载器---Bootstrap类加载器

[2]. Bootstrap类加载器首先在自己的管辖范围jre/lib/rt.jar到了指定类名对应的字节码文件

{1}. 如果找到相应的字节码文件直接加载进来结束本次对指定类的加载

{2}. 如果没找到,Bootstrap按照原路返回到ExtClassLoader将这个要加载的指定类型交给ExtClassLoader去加载

{3}. 如果还没找到,就这样一级级向子类类加载器递推如果在中间的某一级的类加载器找到了指定的类的字节码文件,就结束这次对指定类的加载

[3]. 如果退回到最初要加载类的类加载器的时候,并且在这个类加载器本身的管辖范围内还是没有找到这个指定的类的字节码文件,就会直接抛出ClassNotFoundException这个异常

【总结】某个子类加载器层层向上推进Bootstrap类加载器加载。若最高父类类加载器无法加载指定的类,又开始层层向下递推子类加载器进行加载。如果退回到发起者的类加载器还是没有办法加载指定的类就抛出ClassNotFoundException这个异常

----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------

原创粉丝点击