类加载器详解
2015-09-04 18:14
176 查看
在Java中,一个类用其全限定类名(包名和类名)作为标识,在JVM中,一个类用其全限定类名和其类加载器作为其唯一标识。
当JVM启动时,会形成由3个类加载器组成的初始化类加载器层次结构。
1)Bootstrap ClassLoader:根类加载器,非常特殊,它并不是java.lang.ClassLoader的子类,而是JVM自身实现的。根类加载器所加载的核心类库在java Jdk安装路径jdk1.8_45/jre/lib/文件夹里,比如rt.jar,jce.jar,resources.jar等到。因此,我们可以解释一个现象,为什么程序中可以使用String,System这些核心类库?因为这些核心类库都在rt.jar文件中。
2)Extension ClassLoader:拓展类加载器,负责加载JRE的扩展目录(%J***A_HOME%/jre/lib/ext或者有java.ext.dirs系统属性指定的目录)中的JAR包的类。因此我们可以通过此,为Java拓展核心类库以外的功能了。只需要把自己开发的类打包成JAR文件,然后放入上述的路径即可。
3)System ClassLoader :系统类加载器,负责加载在Java的核心类。负责在JVM启动时紧挨在来自java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。可以通过ClassLoader的静态方法,getSystemClassLoader()来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以系统类加载器作为父加载器。
二、类加载机制
主要是以下3种:
1)全盘负责:当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显式使用另一个加载器来载入。
2)父类委托:先让父类加载器视图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。
3)缓存机制:当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区中。
JVM中4种类加载器的层次结构
根类加载器<------扩展类加载器<------系统类加载器<------自定义加载器
类加载器加载Class大致要经过如下步骤:(结合上述的类加载机制)
1)检测此Class是否载入过,如果有则直接进入返回对应的java.lang.Class对象
2)如果父类加载不存在(如果没有父类加载器,则要么Parent一定是根类加载器要么本身就是根类加载器),则请求使用根类加载器来载入目标类,如果成功载入,则返回对应的Class对象,否则抛出ClassNotFoundException异常。
3)如果父类加载器存在,请求使用父类加载器去载入目标类,如果载入成功则返回对应的Class对象,否则当前类加载器尝试寻找Class文件(从与此ClassLoader相关的类路径中寻找),如果找到了则载入该Class文件,并返回对应的Class对象。如果不成功,则抛出ClassNotFoundException异常
三、创建并使用制定一的类加载器
JVM中除根类加载器之外的所有类加载器(扩展类加载器、系统类就爱在其)都是ClassLoader的子类的实例,通过继承ClassLoader,重写该ClassLoader所包含的Protected方法实现自定义类的加载。
使用自定义ClassLoader可以实现如下常见的功能:
1)执行代码前自动验证数字签名
2)根据用户提供的密码解密代码,从而可以实现代码混淆器来避免反编译Class文件
3)根据用户需求来动态的加载类。
4)根据应用需求把其他数据以字节码的形式加载到应用中
URLClassLoader是ClassLoader的一个实现类,该类也是系统类加载器和拓展类加载器的父类。它可以从本地文件系统获取二进制文件来加载类,也可以从远程主机获取二进制文件来加载类。
当JVM启动时,会形成由3个类加载器组成的初始化类加载器层次结构。
1)Bootstrap ClassLoader:根类加载器,非常特殊,它并不是java.lang.ClassLoader的子类,而是JVM自身实现的。根类加载器所加载的核心类库在java Jdk安装路径jdk1.8_45/jre/lib/文件夹里,比如rt.jar,jce.jar,resources.jar等到。因此,我们可以解释一个现象,为什么程序中可以使用String,System这些核心类库?因为这些核心类库都在rt.jar文件中。
2)Extension ClassLoader:拓展类加载器,负责加载JRE的扩展目录(%J***A_HOME%/jre/lib/ext或者有java.ext.dirs系统属性指定的目录)中的JAR包的类。因此我们可以通过此,为Java拓展核心类库以外的功能了。只需要把自己开发的类打包成JAR文件,然后放入上述的路径即可。
3)System ClassLoader :系统类加载器,负责加载在Java的核心类。负责在JVM启动时紧挨在来自java命令的-classpath选项、java.class.path系统属性,或CLASSPATH环境变量所指定的JAR包和类路径。可以通过ClassLoader的静态方法,getSystemClassLoader()来获取系统类加载器。如果没有特别指定,则用户自定义的类加载器都以系统类加载器作为父加载器。
二、类加载机制
主要是以下3种:
1)全盘负责:当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显式使用另一个加载器来载入。
2)父类委托:先让父类加载器视图加载该Class,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类。
3)缓存机制:当程序中需要使用某个Class时,类加载器先从缓存区中搜寻该Class,只有当缓存区中不存在该Class对象时,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区中。
JVM中4种类加载器的层次结构
根类加载器<------扩展类加载器<------系统类加载器<------自定义加载器
类加载器加载Class大致要经过如下步骤:(结合上述的类加载机制)
1)检测此Class是否载入过,如果有则直接进入返回对应的java.lang.Class对象
2)如果父类加载不存在(如果没有父类加载器,则要么Parent一定是根类加载器要么本身就是根类加载器),则请求使用根类加载器来载入目标类,如果成功载入,则返回对应的Class对象,否则抛出ClassNotFoundException异常。
3)如果父类加载器存在,请求使用父类加载器去载入目标类,如果载入成功则返回对应的Class对象,否则当前类加载器尝试寻找Class文件(从与此ClassLoader相关的类路径中寻找),如果找到了则载入该Class文件,并返回对应的Class对象。如果不成功,则抛出ClassNotFoundException异常
三、创建并使用制定一的类加载器
JVM中除根类加载器之外的所有类加载器(扩展类加载器、系统类就爱在其)都是ClassLoader的子类的实例,通过继承ClassLoader,重写该ClassLoader所包含的Protected方法实现自定义类的加载。
使用自定义ClassLoader可以实现如下常见的功能:
1)执行代码前自动验证数字签名
2)根据用户提供的密码解密代码,从而可以实现代码混淆器来避免反编译Class文件
3)根据用户需求来动态的加载类。
4)根据应用需求把其他数据以字节码的形式加载到应用中
URLClassLoader是ClassLoader的一个实现类,该类也是系统类加载器和拓展类加载器的父类。它可以从本地文件系统获取二进制文件来加载类,也可以从远程主机获取二进制文件来加载类。
相关文章推荐
- hdu4990Reading comprehension 矩阵快速幂
- 升级Xcode之后VVDocumenter-Xcode不能用的解决办法
- LA 3516 Exploring Pyramids 记忆化搜索
- javaSE基础编程——自定义线程
- ELF文件的加载和动态链接过程
- Unity3D学习笔记《Space Shooter》三
- Java并发编程(Callable、Future和CompletionService)
- 面向对象之设计模式的先行军
- LNK1123: 转换到 COFF 期间失败: 文件无效或损坏
- Apache Camel的Header、Property、Body配置示例
- iOS 用post保障传参数的据安全
- 2015第36周六
- 第八集:asp.net登录页面之验证码
- servlet是单例的 所以需要线程安全 以及如何实现线程安全
- SEO优化方式
- 计算机的容量单位
- 监视网络接口TCP状态信息数据有多种工具或命令。下面举例一些:
- 【修正版】Python基础学习(一)——安装与配置python2.7.x环境(linux)
- 图片点击放大,再次点击返回原视图.完美封装,一个类一句代码即可调用.IOS完美实现
- gcd fib