classLoader类加载机制

本文系转载,原文地址:http://shulianghan.iteye.com/blog/1699341

ClassLoader主要作用 :将.class后缀的字节码文件从硬盘上装载到内存中 ;

1.类加载器深入剖析

Java虚拟机与程序的生命周期 :
     当我们执行一个java程序的时候 , 会启动一个JVM进程 , 当程序执行完之后 , JVM进程就消亡了; 
在如下情况下JVM将结束声明周期 :

  • System.exit(int)方法 , 当执行这个方法的时候 , 虚拟机会退出 ; 这个方法传入一个整形参数 , 这个参数是状态吗:  如果这个整形是 0 的话 , 就是正常退出 , 如果不是0的话 , 就是异常退出 ;
  • 程序正常结束;
  • 程序执行过程中 ,遇到了异常或错误 , 而异常终止 : 如果我们在程序中出现了异常 , 而不去处理 , 会将异常一直抛给main函数 ,main函数会将异常抛给JVM , JVM如果处理不了异常 , JVM就会异常退出 ;
  • 由于操作系统出现错误导致JVM进程终止 : JVM所依赖的平台出现错误 , 导致JVM终止 ;

2.类的加载,连接和初始化

  • 加载 :查找并加载类的二进制数据 , 将class字节码文件加载到内存中 ;
  • 连接 :

  •            -验证 : 确保被加载的类的正确性 , 使用javac编译工具生成的字节码文件能通过验证 , 如果不是由javac编译生成的字节码文件 ,如果自己生成的字节码文件不符合JVM虚拟机对字节码文件的要求的话 , 可能会出现验证通不过的情况 ; 比如说随便拿一个文件 , 将后缀名直接修改为.class , 这样的字节码文件肯定不合法; 
               -准备 : 为类的静态变量分配内存 , 并将其初始化为默认值; 
               -解析 : 把类中的符号引用转为直接引用 ;
  • 初始化  :为类的静态变量赋予正确的初始值(正确的值指的是用户赋的值) ;
  •            -好像这个与连接阶段的准备有些重复 , 在连接的准备阶段只是赋予初始变量 , 如果用户给这个变量赋了初始值 ,那么这个变量在连接的准备阶段仍然会赋予初始值 ; 
               -在这个阶段 , 才会真正的将初始值赋给静态变量 ; 

Java程序对类的使用方式有 主动使用 和被动使用 
     所有的JVM实现 , 必须在每个类或者接口 , 被java程序 “首次主动使用” 时才初始化他们; 
主动使用 :

  •  创建类的实例 ;
  •  访问某个类或接口的静态变量 , 或者对该静态变量赋值 ;
  •  调用类的静态方法 ;
  •  反射 : Class.forName(“类名”) ;
  •  初始化一个类的子类 , 看做对父类的主动使用 ; 
  •  java虚拟机启动的时候 , 被标明启动类的类 , 即包含main方法的类 , 程序的入口;


     除了上面6种主动使用之外 , 其它的情况均为被动使用 , 其它情况都不会执行第三步初始化 ;

 

3.类的加载

(1)概念

 

  • 类的加载 : 指的是将类的.class文件中的二进制数据读入到内存 , 将其放在运行时数据区的方法区 , 然后再堆区创建一个java.lang.Class对象 , 用来封装类在方法区内的数据结构 ;
  • 反射 : 反射就是跟句堆区的字节码文件 , 获取方法去的数据结构 ;
  • 解析 : Class对象是由JVM自己创建的 , 所有的对象都是经过Class对象创建 , 这个Class对象是反射的入口通过Class对象 , 可以关联到目标class字节码文件的内部结构 ;

 

    所有的类对应的Class对象都是唯一的一个 , 这个类是由JVM进行创建的 , 并且只有JVM才会创建Class对象

 


类加载的最终产品是位于堆区中的Class对象 ,Class对象封装了类在方法区内的数据结构 , 并且向Java程序员提供了访问方法区内的数据结构的接口(反射用的接口) ;

 

 

(2)加载.class文件的方式

从本地系统中直接加载 : 编译好的.class字节码文件直接从硬盘中加载 ;

通过网络下载.class文件 : class字节码文件放在网络空间中 , 使用URLClassLoader来加载在网络上的.class字节码文件 , 使用默认的父亲委托机制加载字节码文件 ;

zip ,jar 等压缩文件中加载字节码文件 : 在开发的时候 , 导入jar , 就是这种方式 ;

从专有的数据库中提取字节码文件 ;

java源文件动态编译为字节码文件 ;

 

(3)类加载器

  l  Java虚拟机自带的类加载器 :

    -根类加载器 ( Bootstrap ): 是C++写的 , 程序员无法再方法获取到的是一个null值 ;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章