类的加载过程
类的加载分为三个步骤,细分为5个步骤
- 加载 loading :Java 将字节码文件从不同数据源中读取到 JVM 中,并将文件映射为 JVM 认可的数据结构(Class 对象) ,如果输入数据不是 Class 结构,则抛出 ClassFormatError 错误
- 链接 linking
- 验证 : 验证字节信息是否符合 JVM 规范,否则就会被认为验证错误(Verify Error),这一阶段防止了恶意信息或者不合规范的信息危害 JVM 的运行。
- 准备 : 创建类或接口中的静态变量,并为静态变量初始化赋值(自动赋值而非依据代码赋值)并分配内存空间。
- 解析 : 将常量池中的各种引用直接加载到 JVM 中运行。
- 初始化 initialization : 执行类初始化的代码逻辑 () 方法,包括静态属性的赋值,执行静态语句块。
动态加载类的方法
- Class.forName("")
- ClassLoader.loadClass("")
两个方法的区别在于,Class.forName("") 会链接并初始化这个类,而 loadClass 不会去解析这个类。
这是因为 Class.forName("") 调用的实际上是本地方法
private static native Class<?> forName0(String name, boolean initialize,
ClassLoader loader,
Class<?> caller)
throws ClassNotFoundException;
第二个参数 initialize 默认为 true,即初始化该类。
而 loadClass 调用的是
protected Class<?> loadClass(String name, boolean resolve)
throws ClassNotFoundException
{
第二个参数 resolve 默认为 false,即不会解析该类。
抛出 ClassNotFoundException 的原因
在根据字符串类名动态加载类时,未找到类,则抛出 ClassNotFoundException 。常常是由于 类名 错误,导致在类路径下找不到对应的类。
抛出 ClassNotDefFoundError 的原因
以静态的方式加载类,JVM本身使用的方式也是静态加载
编译时,在运行环境中可以加载到类,即可以使用类,调用方法;但在运行时,JVM 尝试去加载类,找不到类的定义,则抛出 ClassNotDefFoundError。常常是 maven jar 包未导入,或者 jar 包版本不对。
自己总结的知识,如果有不对的地方请大佬指正