Java中的类加载机制
Java中的类加载机制是指将类的字节码从文件系统或者网络中加载到JVM(Java虚拟机)中,并将其转换为一个Class
对象的过程。这个过程包括以下几个步骤:
- 加载(Loading):将类的字节码从文件系统或者网络中读取到内存中,并创建一个
Class
对象。 - 链接(Linking):将类的二进制数据合并到JVM中,包括验证(Verification)、准备(Preparation)、解析(Resolution)三个阶段。
- 初始化(Initialization):执行类的静态初始化块和静态变量的初始化。
双亲委派模型
双亲委派模型是java类加载机制中的一个重要概念,它规定了类加载的顺序和责任分配。其基本思想是:当一个类加载器需要加载一个类时,它首先把这个请求委托给它的父类加载器,只有当父类加载器无法完成加载时,才由自身来进行加载。
工作原理
-
类加载器接到加载类的请求:
- 比如,我们在代码中使用
Class.forName("com.example.MyClass")
或者new com.example.MyClass()
时,JVM会启动类加载过程。
- 比如,我们在代码中使用
-
委托父类加载器:
- 当前类加载器会首先把这个请求委托给它的父类加载器。
- 这个过程是递归的,最终会传递到最顶层的类加载器(通常是Bootstrap ClassLoader)。
-
父类加载器尝试加载类:
- 父类加载器会先尝试加载请求的类。如果父类加载器找到了这个类,就返回该类的
Class
对象。 - 如果父类加载器没有找到这个类,则返回给子类加载器。
- 父类加载器会先尝试加载请求的类。如果父类加载器找到了这个类,就返回该类的
-
子类加载器尝试加载类:
- 如果父类加载器未能加载该类,当前类加载器会尝试自己加载这个类。
-
类加载成功:
- 无论是父类加载器还是子类加载器加载到了该类,都会返回该类的
Class
对象。如果所有加载器都未能加载该类,则抛出ClassNotFoundException
。
- 无论是父类加载器还是子类加载器加载到了该类,都会返回该类的
优点
- 安全性:双亲委派模型确保了核心类库(如
java.lang.*
包)不会被自定义的类加载器加载,从而避免核心类库被篡改。 - 避免重复加载:通过委托机制,确保每个类只会被加载一次,避免了重复加载的问题。
类加载器的种类
- Bootstrap ClassLoader:
- 负责加载JVM的核心类库,通常是
$JAVA_HOME/lib
下的类。
- 负责加载JVM的核心类库,通常是
- Extension ClassLoader:
- 负责加载扩展类库,通常是
$JAVA_HOME/lib/ext
目录下的类。
- 负责加载扩展类库,通常是
- Application ClassLoader:
- 负责加载应用程序类路径(classpath)下的类,是用户自定义类加载器的默认父加载器。
总结
- 类加载机制:将类的字节码加载到内存中,转换为
Class
对象,并进行验证、准备和初始化。 - 双亲委派模型:类加载器在加载类时,会优先委托给父类加载器,只有当父类加载器无法完成加载时,才由自身进行加载。这种机制提高了系统的安全性和稳定性。
通过理解Java的类加载机制和双亲委派模型,你可以更好地掌握Java应用程序的运行过程和类的加载流程。