首页 > 代码库 > 类加载和类加载器
类加载和类加载器
什么是类加载
类加载指的是将.Class文件读入内存,并为之创建一个java.lang.Class对象,也就是说程序使用任何类时,系统都会为之建立一个java.lang.Class对象
何时类加载和类加载步骤
当程序主动使用某个类时,系统会通过加载,连接,初始化三个步骤来对该类进行初始化,JVM将会连续完成这三个步骤,也把这三个步骤统称为类加载或类初始化。
主动触发类加载的情况
1)创建类的实例,也就是new一个对象
2)访问某个类或接口的静态变量,或者对该静态变量赋值
3)调用类的静态方法
4)反射(Class.forName("com.lyj.load"))
5)初始化一个类的子类(会首先初始化子类的父类)
6)JVM启动时标明的启动类,即文件名和类名相同的那个类
类加载步骤
1) 装载:查找并加载类的二进制数据;
2)链接:
验证:确保被加载类的正确性;
准备:为类的静态变量分配内存,并将其初始化为默认值;
解析:把类中的符号引用转换为直接引用;
3)初始化:为类的静态变量赋予正确的初始值;
准备阶段和初始化阶段的解释: 如果类中有语句:private static int a = 10,它的执行过程是这样的,首先字节码文件被加载到内存后,先进行链接的验证这一步骤,验证通过后准备阶段,给a分配内存,因为变量a 是static的,所以此时a等于int类型的默认初始值0,即a=0,然后到解析(后面在说),到初始化这一步骤时,才把a的真正的值10赋给a,此时a=10。
类加载器
1.Bootstrap( 加载系统类): c++写的, 该类不能访问
加载路径: %JAVA_HOME%/jre/lib , sun.boot.class.path 指向的目录或jar , %JAVA_HOME%/jre/classes中的类
2. ExtClassLoader ( 加载扩展类): java写的静态内部类,具体实现是 sun.misc.Launcher$ExtClassLoader
加载路径: %JAVA_HOME%/jre/lib/ext , java.ext.dirs 指向的目录或jar
3. AppClassLoader类(加载应用类) : 是Java程序默认的类加载器, java写的 静态内部类,具体实现是 sun.misc.Launcher$AppClassLoader
加载路径: java.class.path 指向的目录或jar
一个项目中需要加载的类:
1.javaAPI:如String类
2.外部的jar:比如sprin框架
3.自定义的:
1)自己写的类
2)继承javaAPI,自己的实现代替javaAPI
三者之间的关系是
1. Bootstrap是爷爷、ExtClassLoader是爸爸、AppClassLoader是孩子(孙子)
2. ExtClassLoader和AppClassLoader都是由Bootstrap加载的:
虚拟机初始化动作完成后,会产生第一个类加载器 Bootstrap Loader ,Bootstrap Loader会加载 ExtClassLoader 并设定其 Parent 为 null ,代表其父加载器为 BootstrapLoader
然后Bootstrap Loader 再要求加载 AppClassLoader 并设定其 Parent 为之前产生的 ExtClassLoader 实体
加载器加载的二进制数据来源
1)从本地系统直接加载Class文件,如放在了bin目录下
2)通过网络下载.class文件
3)从zip,jar等归档文件中加载.class文件,如JDBC编程时用到的数据库驱动类就是放在jar文件中,JVM可以从jar文件中直接加载该Class文件
4)从专有数据库中提取.class文件
5)将Java源文件动态编译为.class文件(服务器)
类加载和类加载器