JVM-ClassLoader
来源:互联网 发布:成都电视台网络直播 编辑:程序博客网 时间:2024/06/06 00:35
1. ClassLoader基本概念
与C或c++编写的程序不同,Java程序并不是一个可执行文件,而是由许多独立的类文件组成的,每一个文件对应一个Java类。此外,这些类文件并非全部都装入内存,而是根据程序需要遵渐载入。ClassLoader是JVM实现的一部分。
ClassLoader包括:
bootstrap classloader(启动类加栽器),ClassLoader在JVM运行的时候加载Java核心的API,以满足Java程序最基本的需求,其中就包括用户定义的ClassLoader,这里所谓的用户定义,是指通过Java程序实现的两个ClassLoader: -个ExtClassLoader,它的作用是用采加载Java的扩展API,也就是,lib/ext中的类;第二个是AppClassLoader,它是用来加载用户机器上CLASSPATH设置目录中的Class类,通常在没有指定ClassLoader的情况下,程序员自定义的类就由该ClassLoadcr进行加载。
2.ClassLoader加载流程
当运行一个程序的时候,JVM启动,运行bootstrap classloader,该ClassLoader加载Java核心API(ExtClassLoader和AppClassLoader也在此时被加栽),然后调用ExtClassLoader加载扩展API,最后AppClassLoader加载CLASSPATH目录下定义的Class,这就是一个程序最基本的加载流程。
3.类加载的过程->父类委托模式
loadClass{//首先检查该name的class是否被加载Class c=findLoadClass(name);if(c==null){ if(parent!=null){ //如果parent不为null,则调用parent的loadClass进行加载 c=parent.loadClass(name,false); }else{ //如果parent为null,则调用BootstrapClassLoader进行加载 c=findBootstrapClass(name); }}//如果仍然没有加载成功,则调用自身的findClass进行加载c=findClass(name);if(resolve){ reaolveClass(c);}return c;}
从上面一段代码中可以看出,一个类加载的过程使用了一种父类委托模式。
为什么要使用这种父类委托模式呢?
1.这样可以避免重复加载,当父类已经加栽了该类的时候,就没有必要子ClassLoader再加载一次。
2.考虑到安全因素,如果不使用这种委托模式,那么可以随时使用自定义的String来动态替代Java核心API中定义的类型,这样会存在非常大的安全隐患,而父类委托的方式就可以避免这种情况,因为String已经在启动时被加载,所以,用户由定义类是无法加载一个自定义的ClassLoader。
重要方法
1. loadClass方法
ClassLoader.loadClass0是ClassLoader的入口点。该方法的定义如下:
Class loadClass( String name, boolean resolve)
2. defineClass方法
defineClass方法接受由原始字节组成的数组,并把它转换成Class对象。原始数组包含如从文件系统或网络装入的数据。defineClass管理JVM的许多复杂的实现层面——它把字节码分析成运行时数据结构、校验有效性等。因为
defineClass方法被标记成final的,所以也不能覆盖它。
3. findSystemClass方法。
findSystemClass方法从本地文件系统装入文件。它在本地文件系统中寻找类文件,如果存在,就使用defineClsass将原始字节转换成Class对象,以将该文件转换成类。当运行Java应用程序时,这是JVM正常装入类的默认机制。对于
定制的ClassLoader,只有在尝试其他方法装入类之后,再使用findSystemClass。
这是因为ClassLoader是负责执行装入类的相关步骤,不负责所有类的所有信息。例如,即使ClassLoader从远程的Web站点装入了某些类,仍然需要在本地机器上装入大量的基本Java库。而这些类库不是我们所关心的,所以要JVM以默认
方式从本地文件系统装入它们,这就是findSystemClass的用途。
4. resolveClass方法
正如前面所提到的,可以不完全地(不带解析)装入类,也可以完全地(带解析)装入类。当编写我们自己的loadClass时,可“调用resolveClass,这取决于loadClass的resolve参数的值。
5. findLoadedClass方法
findLoadedClass充当一个缓存:当请求loadClass装入类时,它调用该方法来查看ClassLoader是否已装入这个类,这样可以避免重新装八已存在类所造成的麻烦。
6.findClass方法:
loadClass默认实现调用这个新方法。findClass的用途包含ClassLoader的所有特殊代码,而无须要复制其他代码(例如,当专门的方法失败时,调用系统ClassLoader)。
为了创建自己的类装载器,应该扩展ClassLoader类,这是一个抽象类,可以创建一个
FileClassLoaderextends ClassLoader,然后覆盖ClassLoader中的findClass( String name)方法,这个方法通过类的名字而得到一个Class对象。
8) forName方法
Class类中有一个静态方法forName,这个方法和ClassLoader中的loadClass方法的目的一样,都是用来加载class的,但是两者在作用上却有所区别。
在Java API文档中,loadClass方法的定义是protected,也就是说,该方法是被保护的,而用户使用的方法是一个参数,一个参数的loadclass方法实际上就是调用了两个参数,第二个参数默认为false。因此,在这里可得看出通过loadClass加载类实际上就是加载的时候并不对谊类进行解释,因此不会初始化该类。而Class粪的forName方法则相反,使用forName加载的时候就会将Class进行解释和初始化。
下 面给出的Java中ClassLoader中的描述,哪些描述是正确的? ( )
A. ClassLoader没有层次关系
B.所有类中的ClassLoader都是AppClassLoader
c.通过Class.forName(String className),能够动态加载一个类
D.不同的ClassLoader加载同一个Class文件,所得的类是相同的
- jvm classloader
- JVM classLoader
- JVM ClassLoader
- JVM ClassLoader
- JVM CLASSLOADER
- JVM classloader
- JVM-ClassLoader
- JVM-ClassLoader
- jvm - ClassLoader
- JVM ClassLoader机制
- JVM学习-ClassLoader
- JVM装载类(ClassLoader)
- JVM之二-ClassLoader
- 转:jvm classloader
- JVM中的classloader
- jvm原理 ClassLoader javac
- 初探JVM-ClassLoader源码
- jvm classLoader architecture:
- 浅谈C#委托和事件
- Manacher(回文字符串)
- MySQL自学-入门篇
- 感受异或的神奇
- 简单的struts2案例
- JVM-ClassLoader
- mysql实现行转列的两个方式
- Remove Duplicates from Sorted Array
- 黑马程序员-集合的概述-List
- import-module的注意事项与NDK_MODULE_PATH的配置
- java中,数值型Double运算出错问题
- JAVA入门基础文章3-类的概念-什么是继承
- 文本文件解析
- Java比较String ==和equals() 解析