`
wangxuliangboy
  • 浏览: 208358 次
  • 性别: Icon_minigender_1
  • 来自: 上海
文章分类
社区版块
存档分类
最新评论

JAVA类加载器分析

阅读更多

JVM三种预定义类型类加载器:

启动(Bootstrap)类加载器:引导类装入器是用本地代码实现的类装入器,它负责将 <Java_Runtime_Home>/lib 下面的类库加载到内存中,但是虚拟机出于安全等因素考虑,不会加载< Java_Runtime_Home >/lib存在的陌生类,开发者通过将要加载的非JDK自身的类放置到此目录下期待启动类加载器加载是不可能的

标准扩展(Extension)类加载器:扩展类加载器是由 Sun ExtClassLoadersun.misc.Launcher$ExtClassLoader 实现的。它负责将 < Java_Runtime_Home >/lib/ext 或者由系统变量 java.ext.dir 指定位置中的类库加载到内存中

系统(System)类加载器:系统类加载器是由 Sun AppClassLoadersun.misc.Launcher$AppClassLoader)实现的。AppClassLoader是加载Classpath中配置的类库.

 

类加载双亲委派机制:

JVM在加载类时默认采用的是双亲委派机制。通俗的讲,就是某个特定的类加载器在接到加载类的请求时,首先将加载任务委托给父类加载器,依次递归,如果父类加载器可以完成类加载任务,就成功返回;只有父类加载器无法完成此加载任务时,才自己去加载。关于虚拟机默认的双亲委派机制,

ClassLoader主要是通过loadClass()来加载类的。

loadClass()方法的代码:

// 首先判断该类型是否已经被加载

        Class c = findLoadedClass(name);

        if (c == null) {

            //如果没有被加载,就委托给父类加载或者委派给启动类加载器加载

            try {

                if (parent != null) {

//如果存在父类加载器,就委派给父类加载器加载

                    c = parent.loadClass(name, false);

                } else {

//如果不存在父类加载器,就检查是否是由启动类加载器加载的类,通过调用本地方法native Class findBootstrapClass(String name)

                    c = findBootstrapClass0(name);

                }

            } catch (ClassNotFoundException e) {

        // 如果父类加载器和启动类加载器都不能完成加载任务,才调用自身的加载功能

                c = findClass(name);

            }

        }

通过分析上面代码,可以得出类加载器的加载顺序:

BootstrapClassLoader-----ExtensionClassLoader----AppClassLoader---自定义的类加载器

怎么知道当前类使用了什么类加载器呢?

System.out.println(this.getClass().getClassLoader());----得到当前的类加载器

 

System.out.println(this.getClass().getClassLoader().getParent());----得到当前类的父加载器

System.out.println(this.getClass().getClassLoader().getParent().getParent());----得到当前类的父加载器的父加载器

 

假如当前类的加载器为sun.misc.Launcher$AppClassLoader@197d257,那么它的父加载器则为

sun.misc.Launcher$ExtClassLoader@7259da,但是扩展类加载器的父加载器则为NULL

 

扩展类加载器的父加载器为什么会为NULL呢?

由于引导类加载器涉及到虚拟机本地实现细节,开发者无法直接获取到启动类加载器的引用,所以不允许直接通过引用进行操作。

 

扩展类加载器的父加载器怎么使父加载器为NULL的呢?

 扩展类加载器(ExtClassLoader调用ClassLoader(ClassLoader parent)构造函数将父类加载器设置为null

但是我们可以分析前面的代码。。当父加载器为NULL,JAVA会调用启动类加载器(findBootstrapClass0(name)

如何实现我们的自定义类加载器呢?

实现自定义加载器其它很简单。只要实现ClassLoader的findClass()方法就行了。

大概如下:

findClass(String name){

byte[] buffer=//读取文件的字节数组

return defineClass(buffer,0,buffer.length);

}

当自定义类加载器加载的类有继承相应的类或实现相应接口的话,必须把相应的父类或接口拷贝到同一路径。因为类加载器在加载子类时,会同时加载父类。

关于类的转型问题:

由于类加载器是相互隔离的,当classLoaderA加载了A类,classLoaderB也加载了A类。这个类对象是不能互相转型的。会报ClassCastException异常。

假如自定义类加载器加载A类时,而A类又实现了接口B时,我们是可以将A类的实例转成B接口的。原因是类加载器在加载A类时,会同时加载A类的所有父类(包括接口).

JAVA类加载器采用了委托模式。当一个类对象己经被加载了,就不会在去加载该类。还是直接返回。那么如何重新加载这个类呢?

实现自定义的类加载器,当类加载完成后。调用相应方法,然后在去掉相应类加载器的引用。这样类不会在存在类加载器中了。

比如:classLoaderA=null(去掉A加载器的引用)

 

 

 

 

 

 

 

 

5
0
分享到:
评论
3 楼 lixia0417 2010-04-20  
不错,扩展了很多知识;
2 楼 PointOnLine 2008-12-20  
最近在了解安全机制,大部分都谈论的是关于类加载器。不知道数字签名是不是与这个类加载器也相关?
1 楼 monner 2008-10-14  
有深度!学习了!谢谢博主带来如此精彩的文章!

相关推荐

    JAVA类加载器分析--热部署的缺陷(有代码示例,及分析)

    Eclipse 工程代码 博文链接:https://flyfoxs.iteye.com/blog/2080502

    java类加载原理分析

    java类加载原理分析,引导类加载器,扩展类加载器,系统类加载器(也叫应用类加载器)

    Java类加载器和类加载机制实例分析

    主要介绍了Java类加载器和类加载机制,结合实例形式分析了java类加载器与类加载机制原理、实现方法及相关操作技巧,需要的朋友可以参考下

    java类的加载过程以及类加载器的分析

    给大家详细讲述了java类的加载过程以及类加载器的相关知识点内容,有需要的朋友可以学习下。

    Java实现的自定义类加载器示例

    主要介绍了Java实现的自定义类加载器,结合具体实例形式分析了java自定义类加载器的原理与具体实现技巧,需要的朋友可以参考下

    java类文件混合加密算法的研究与分析_邹煜.caj

    近年来,企业和java开发人员针对java类文件的...所以文章采用JNI结合类加载器装载等java技术设计了一套不透明性较大的类 文件保护机制。并分析和测试了这套类文件保护机制的有效性与可靠性。

    深入研究Java 的类加载机制

    Java 类的动态装载机制是Java 虚拟机的一项核心技术,可以在运行时刻动态地加载或替换系统的 某些功能模块,而不影响系统...及应用,分析了类装载器的结构、用途,阐述了利用自定义类装载器装载并执行Java 类的过程。

    java深度历险

    创建自己的类加载器 14 参考资料 15 JAVA线程:基本概念、可见性与同步 16 JAVA线程基本概念 16 可见性 17 JAVA中的锁 18 JAVA线程的同步 19 中断线程 20 参考资料 20 JAVA垃圾回收机制与引用类型 22 JAVA垃圾回收...

    【图解版】深入分析ClassLoader类加载工作机制

    【图解版】深入分析ClassLoader类加载工作机制,从原理到JVM的装载过程,详情分析了ClassLoader加载类以及自定义类加载器的过程,不可用于商业用途,如有版权问题,请联系删除!

    java源码包---java 源码 大量 实例

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    JAVA上百实例源码以及开源项目源代码

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    java源码包4

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...

    JAVA上百实例源码以及开源项目

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码,...

    java虚拟机的奥秘ClassLader源码分析与案例讲解

    适合刚毕业的初学者,深入浅出的了解java虚拟机原理,类加载器,案例讲解

    java源码包3

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...

    java开源包8

    Spring4GWT ...JARP是为petri 网提供的一个Java编辑器,基于ARP分析器。可以将网络图导出为 GIF, JPEG, PNG, PPM, ARP and PNML (XML based)文件格式。使用了优秀的JHotDraw 5.2 框架。 activemq...

    java源码包2

     Java二进制IO类与文件复制操作实例,好像是一本书的例子,源代码有的是独立运行的,与同目录下的其它代码文件互不联系,这些代码面向初级、中级Java程序员。 Java访问权限控制源代码 1个目标文件 摘要:Java源码...

    java内存分析_java_

    类加载器将class文件字节码(可以来自文件、网络、数据库等)内容加载到内存中,并将这些静态数据转换成方法区 中的运行时数据结构,在堆中生成一个代表这个类的java.lang.Class对象,作为方法区类数据的访问入口...

    最新Java面试题视频网盘,Java面试题84集、java面试专属及面试必问课程

    │ Java面试题40.jQuery中页面加载完毕事件.mp4 │ Java面试题41.jQuery中Ajax和原生js实现Ajax的关系.mp4 │ Java面试题42.简单说一下html5.mp4 │ Java面试题43.简单说一下css3.mp4 │ Java面试题44.bootstrap的是...

    斯坦福的句法分析器及在java中调用的源代码

    一个斯坦福的句法分析器包stanford-parser.jar,以及在java工程中加载汉语句法分析器模型包和英语句法分析器模型的调用源程序

Global site tag (gtag.js) - Google Analytics