0%

类加载器

类加载器

类加载器最根本的一个作用是从包含字节代码的字节流中定义出虚拟机中的Class类的对象,得到Class类的对象之后,一个Java类就可以在虚拟机中自由使用,包括创建新的对象或调用类中的静态方法。

Java虚拟机中的类加载器负责加载来自文件系统、网络或其他来源的类文件。Java虚拟机中的类加载器默认使用的是双亲委派模式。

其中三种默认使用的类加载器,分别是Bootstrap ClassLoader、Extension ClassLoader和System ClassLoader(也称为Application ClassLoader),每种类加载器已经确定从哪个位置加载类文件。

Bootstrap ClassLoader负责加载JDK自带的rt.jar包中的类文件,是所有的类加载器的父加载器

Extension ClassLoader负责加载Java扩展类库,从jre/lib/ext目录下或者java.ext.dirs系统属性指定的目录下加载类。

Application ClassLoader负责从classpath环境变量中加载类文件,classpath环境变量通常由”-classpath”或”-cp”命令行选项来定义,或是由JAR中Mainifest文件的classpath属性指定。

双亲委派机制

类加载双亲委派

根据双亲委派机制,在加载类文件时,子加载器首先会将加载请求委托给它的父加载器,父加载器会检测自己是否已经加载过该类,如果已经加载则加载过程结束;如果未加载则请求继续向上传递,直到Bootstrap ClassLoader。如果在请求向上委托的过程中,始终未检测到该类已加载,则从Bootstrap ClassLoader开始尝试从其对应路径中加载该类文件,如果加载失败,则向下传递,直到发起请求的子加载器位置为止。

双亲委派的作用

  • 子加载器可以使用父加载器已加载的类,而父加载器无法使用子加载器已加载的类
  • 父加载器已加载过的类无法被子加载器再次加载,保证JVM的安全性和稳定性

注意:在Servlet规范中对于Web应用的类加载器的实现方式的推荐做法是使用当前类加载器优先的策略来代替默认的双亲委派,目的是为了解决web应用中的第三方库和容器本身使用的第三方库冲突的问题。如果采用双亲优先的话,那么容器中提供的第三方库会被优先加载,web应用中使用了同样的库,但是版本不同,会导致web应用出现错误