JVM类加载器
类加载器机制加载阶段需要虚拟机做的第一件事“通过类的全限定名,获取该类的二进制字节流”实现这个动作的代码被称为类加载器(Class Loader)粗略可分为两部分:启动类加载器(BootStrap Class Loader):由C实现,属于虚拟机内部的一部分其他类加载器:都由Java实现,独立于虚拟机外部,统统继承自java.lang.ClassLoader抽象类详细划分...
·
类加载器机制
- 加载阶段需要虚拟机做的第一件事“通过类的全限定名,获取该类的二进制字节流”实现这个动作的代码被称为类加载器(Class Loader)
- 粗略可分为两部分:
- 启动类加载器(BootStrap Class Loader):由C实现,属于虚拟机内部的一部分
- 其他类加载器:都由Java实现,独立于虚拟机外部,统统继承自java.lang.ClassLoader抽象类
- 详细划分:Java一直保持着三层类加载、双亲委派模式的类加载架构
类与类加载器
- 类加载器仅仅在加载阶段露脸一次,但其实际作用远超整个类加载过程;每个类都需要加载他的类加载器与这个类本身共同确定其在虚拟机中的唯一性
- 比较两个类是否相等的唯一前提条件是:必须由同一类加载器加载;即便是源于同一个class文件或是由同一虚拟机加载只要类加载器不一致,这两个类必定不相等
- 相等:可以使用Class中的equals()、isAssignableFrom()、isInstanceof()方法或者通过instanceof关键字做对象所属关系判定等情况
三层类加载
- 启动类加载器(Bootstrap Class Loader)
- 作为顶层类加载器,由C实现,属于虚拟机内部,他负责加载<JAVA_HOME>/lib目录下,或者由-XBootClassPath参数所指定的路径中的所有能够被虚拟机识别的类库
- 识别类库:按文件名识别(rt.jar,tools.jar),没能被识别的类库不能加载,启动类加载器只能加载系统中存储的类库
- 扩展类加载器(Extension Class Loader)
- 由Java实现,负责加载<JAVA_HOME>/lib/ext目录下,或者被java.ext.dirs系统变量所指定的所有类库
- 应用程序类加载器(Application Class Loader)
- 由java实现,又被称为系统类加载器,负责加载用户路径ClassPath上的所有类库;开发人员可以在代码中使用系统类加载器,一般情况下只要没有自定义类加载器,使用的就是系统类加载器
双亲委派模式
- 双亲委派模式中要求除了最顶层的启动类加载器之外,其他的类加载器必须拥有父类加载器;类加载器中的父子关系与通常情况下的类继承关系有所区别,类加载器中通过组合关系复用父类加载器中的相关代码
- 双亲委派模式于JDK1.2时引入
- 工作原理:当类加载器遇到加载任务时,不会考虑自己加载,而是委托给他的父类加载器,如果父类加载器上面还有父类加载器就向上委托,依次递归直至到达顶层的启动类加载器;如果父类加载器完成加载任务则成功返回;如果父类加载器未能完成加载,则会委托给他的子类加载器由子类加载器完成加载任务
- 三大优势:
- Java类会随着他的类加载器共同具备一种带有优先级的层次关系,可以通过层次关系避免类加载器的重复加载,如果父类加载器已经加载过这个类了那么子类加载器就不必再次加载了
- Java核心API的常用类型不允许改变,如果通过网络传输过来一个java.lang.Integer类,通过双亲委派模式委托给顶层的启动类加载器加载,启动类加载器会去路径中寻找,发现自己加载过这个类,不会再去加载网上传过来的这个类而是给他返回自己加载好的Integer类,保证Java核心API不会被篡改
- 如果在java.lang包中胡编一个java.lang.TigerUydb类,通过双亲委派模式委托给启动类加载器,启动类加载器的路径中找不到这个类,则会向下委托给他的子类加载器,最终由系统类加载器完成加载;但是不允许这种操作,访问java.lang需要权限,否则会报错:java.lang.SecurityException:Rihibt pakeage name:java.lang
更多推荐
已为社区贡献7条内容
所有评论(0)