概述
类加载器
类加载器实际上可以包含一条加载器链,但是只有一个原声类加载器,可以挂接额外类加载器
原生类加载器
原生类加载的是所谓的可信类,如:JavaAPI等额外类加载器
额外类加载器用来满足自身的特殊需求,如:以某种特殊方式加载类,以支持WEB服务器应用等
类的动态加载
类的动态加载分为三个步骤:
加载
由类加载器执行,该步骤将查找字节码,并从字节码中创建一个Class对象链接
链接将验证类中的字节码,为静态域分配存储空间,并且如果必须的话将解析这个类创建其它类的所有引用初始化
如果该类具有超类,则对其初始化,执行静态初始化器和静态初始化块
“惰性”初始化
当程序创建第一个对类的静态成员的引用时,就会 加载 该类;
根据java虚拟机规范,所有java虚拟机实现必须在每个类或接口被java程序首次 主动使用 时才初始化。
主动使用有如下几种
创建类的实例
访问某个类或者接口的静态域(静态变量、方法)
- 如果访问静态编译时常量(static final)不会导致类的初始化
- 构造方法也是类的静态方法,因此使用 new关键字会被当成是对静态成员的引用
1 | package org.gavin.clazz; |
- 反射(Class.forName(xxx.xxx.xxx))
1 | package org.gavin.clazz; |
- 初始化一个类的子类(相当于对父类的主动使用),不过直接通过子类引用父类元素,不会引起子类的初始化
1 | package org.gavin.clazz; |
- Java虚拟机被标明为启动类的类(包含main方法的类)
获取Class对象
- 类字面量常量 .class
- 反射 Class.forName( )
- 实例对象 obj.getClass
参考
Java编程思想 (14章)
Java系列笔记(1) - Java 类加载与初始化