Java深入分析ClassLoader

发布于 2021-04-17 02:25 ,所属分类:知识学习综合资讯


目录

介绍

功能

主要方法

加载机制

常见的类加载错误

实现ClassLoader

实现类的热部署




详解

介绍

ClassLoader负责将Class加载到JVM中,后续会由JVM的执行引擎去执行字节码指令(java虚拟机规范中定义了执行引擎遇到的每条字节码指令该处理什么),得到执行结果。




功能

  • 将Class加载到JVM中;

  • 审查每个类该由谁加载(父优先的等级加载机制);

  • 将Class字节码重新解析成JVM统一要求的对象格式。




主要方法

  • defineClass(byte[],int,int)

    转换字节码为JVM可以识别的class文件

  • findClass(String)

    获取需要加载类的字节码文件

  • loadClass(String)

    运行期间主动加载一个自己指定的类

    this.getClass().getClassLoader.loadClass(String)

  • resolveClass(Class)

    将class文件解析成JVM所规定的指令集形式并被链接




加载机制

父优先的等级加载机制。


通常定义三层,从下到上依次:

  • AppClassLoader(classpath)

  • ExtClassLoader()

  • BootstrapClassLoader()


AppClassLoader和ExtClassLoader都继承URLClassLoader,并隐式继承了Loader,遵循了父优先。


BootstrapClassLoader只服务于自身。




常见的类加载错误

classNotFoundException

  • 通过 class.forname(), this.getClass().getClassLoader().loaderClass(), findSystemClass()显式加载类;

  • 查到classpath下有没有该类;

  • 不知道classpath,可以通过this.getClass().getClassLoader().getResource("").toString()来获取。



NoClassDefFoundException

  • 属于隐式加载问题,检查每个类的父类是否在当前的classpath下;

  • 是否有缺失包名的情况。



UnsatisfiedLinkError

  • 通常发生在启动JVM的时候不小心把某个lib删除导致(找不到某个库文件)。



ClassCastException

  • 类型转换错误,细心检查;

  • 在强转前使用instanceof来判断类型转换是否正确。



ExceptionInInitializerError




实现ClassLoader

继承ClassLoader,重写findClass, definedClass, resolveClass方法。

(点击查看大图)




实现类的热部署

  • 动态加载类,并resolve()主动链接;

  • 旁门左道方法可实现,不让保存类的状态。




相关资源