1、类加载机制
虚拟机把类的数据从class加载到内存,并对数据进行校验、解析和初始化,最终形成虚拟机可以直接使用的Java类型,即是虚拟机的类加载机制。
类加载器并不需要等到某个类被“首次主动使用”时再加载它,JVM规范允许类加载器在预料某个类将要被使用时就预先加载它,如果在预先加载的过程中遇到了.class文件缺失或存在错误,类加载器必须在程序首次主动使用该类时才报告错误,如果这个类一直没有被程序主动使用,那么类加载器就不会报告错误。
加载的类都被缓存,缓存找不到才会加载。
2、类加载步骤
类加载步骤如下:
1)装载
通过类的全限定名加载类的字节流,在内存中创建class的对象。
2)链接
验证:验证class文件的字节流数据,确保不会危害虚拟机自身安全;
准备:准备操作之后,不带final静态变量并没有赋值,在初始化阶段才会赋值;而带final的静态变量在此阶段就会赋值;
解析:将符号引用解析为直接引用。
3)初始化
成员变量初始化;给类的静态变量赋值。
3、类加载器
类加载器分为4种:
- Bootstrap ClassLoader:由C++实现,没有父类。
- Extension ClassLoader:由Java语言实现,父类加载器为null。
- Application ClassLoader:由Java语言实现,父类加载器为ExtClassLoader。一般继承这个类来实现自己的类加载机制;
- Custom ClassLoader:父类加载器肯定为AppClassLoader。
双亲委派机制:除顶层的启动类加载器以外,其余的类加载器都有父加载器,这种父子关系并非类继承关系,而是类组合关系。当类加载器收到加载请求,不会直接加载,而是先委派给父加载器加载,当父加载器加载失败时,才会尝试加载。
这种机制的意义在于,避免了类的重复加载。
4、类初始化时机
以下几种情况,如果类未初始化会对类进行初始化:
- 创建类的实例;
- 访问类的静态变量或静态方法;
- 当初始化一个类时,发现其父类还未初始化,则先出发父类的初始化;
- 虚拟机启动时,定义了main()方法的那个类先初始化;
- 反射。