这篇文章介绍classLoader算是比较详细了,顺手转来了。为后天的Google笔试,这两天拼命看啊- -

版权信息: 可以任意转载, 转载时请务必以超链接形式标明文章原文出处, 即下面的声明.

原文出处:http://blog.chenlb.com/2009/06/java-classloader-architecture.html

jvm classLoader architecture:

  1. Bootstrap ClassLoader/启动类加载器 
    主要负责jdk_home/lib目录下的核心 api 或 -Xbootclasspath 选项指定的jar包装入工作。
  2. Extension ClassLoader/扩展类加载器 
    主要负责jdk_home/lib/ext目录下的jar包或 -Djava.ext.dirs 指定目录下的jar包装入工作。
  3. System ClassLoader/系统类加载器 
    主要负责java -classpath/-Djava.class.path所指的目录下的类与jar包装入工作。
  4. User Custom ClassLoader/用户自定义类加载器(java.lang.ClassLoader的子类) 
    在程序运行期间, 通过java.lang.ClassLoader的子类动态加载class文件, 体现java动态实时类装入特性。

类加载器的特性:

  1. 每个ClassLoader都维护了一份自己的名称空间, 同一个名称空间里不能出现两个同名的类。
  2. 为了实现java安全沙箱模型顶层的类加载器安全机制, java默认采用了 " 双亲委派的加载链 " 结构。

classloader-architecture

classloader-class-diagram

类图中, BootstrapClassLoader是一个单独的java类, 其实在这里, 不应该叫他是一个java类。因为,它已经完全不用java实现了。它是在jvm启动时, 就被构造起来的, 负责java平台核心库。

自定义类加载器加载一个类的步骤

classloader-load-class

ClassLoader 类加载逻辑分析, 以下逻辑是除 BootstrapClassLoader 外的类加载器加载流程:

  1. // 检查类是否已被装载过
  2. Class c = findLoadedClass(name);
  3. if (c == null ) {
  4. // 指定类未被装载过
  5. try {
  6. if (parent != null ) {
  7. // 如果父类加载器不为空, 则委派给父类加载
  8. c = parent.loadClass(name, false );
  9. } else {
  10. // 如果父类加载器为空, 则委派给启动类加载加载
  11. c = findBootstrapClass0(name);
  12. }
  13. } catch (ClassNotFoundException e) {
  14. // 启动类加载器或父类加载器抛出异常后, 当前类加载器将其
  15. // 捕获, 并通过findClass方法, 由自身加载
  16. c = findClass(name);
  17. }
  18. }

线程上下文类加载器
java默认的线程上下文类加载器是 系统类加载器(AppClassLoader)。

  1. // Now create the class loader to use to launch the application
  2. try {
  3. loader = AppClassLoader.getAppClassLoader(extcl);
  4. } catch (IOException e) {
  5. throw new InternalError(
  6. "Could not create application class loader" );
  7. }
  8. // Also set the context class loader for the primordial thread.
  9. Thread.currentThread().setContextClassLoader(loader);

以上代码摘自sun.misc.Launch的无参构造函数Launch()。

使用线程上下文类加载器, 可以在执行线程中, 抛弃双亲委派加载链模式, 使用线程上下文里的类加载器加载类.
典型的例子有, 通过线程上下文来加载第三方库jndi实现, 而不依赖于双亲委派.
大部分java app服务器(jboss, tomcat..)也是采用contextClassLoader来处理web服务。
还有一些采用 hotswap 特性的框架, 也使用了线程上下文类加载器, 比如 seasar (full stack framework in japenese).

线程上下文从根本解决了一般应用不能违背双亲委派模式的问题.
使java类加载体系显得更灵活.

随着多核时代的来临, 相信多线程开发将会越来越多地进入程序员的实际编码过程中. 因此,
在编写基础设施时, 通过使用线程上下文来加载类, 应该是一个很好的选择。

当然, 好东西都有利弊. 使用线程上下文加载类, 也要注意, 保证多根需要通信的线程间的类加载器应该是同一个,
防止因为不同的类加载器, 导致类型转换异常(ClassCastException)。

为什么要使用这种双亲委托模式呢?

  1. 因为这样可以避免重复加载,当父亲已经加载了该类的时候,就没有必要子ClassLoader再加载一次。
  2. 考虑到安全因素,我们试想一下,如果不使用这种委托模式,那我们就可以随时使用自定义的String来动态替代java核心api中定义类型,这样会存在非常大的安全隐患,而双亲委托的方式,就可以避免这种情况,因为String已经在启动时被加载,所以用户自定义类是无法加载一个自定义的ClassLoader。

java动态载入class的两种方式:

  1. implicit隐式,即利用实例化才载入的特性来动态载入class
  2. explicit显式方式,又分两种方式:
    1. java.lang.Class的forName()方法
    2. java.lang.ClassLoader的loadClass()方法

用Class.forName加载类

Class.forName使用的是被调用者的类加载器来加载类的。
这种特性, 证明了java类加载器中的名称空间是唯一的, 不会相互干扰。
即在一般情况下, 保证同一个类中所关联的其他类都是由当前类的类加载器所加载的。

  1. public static Class forName(String className)
  2. throws ClassNotFoundException {
  3. return forName0(className, true , ClassLoader.getCallerClassLoader());
  4. }
  5. /** Called after security checks have been made. */
  6. private static native Class forName0(String name, boolean initialize,
  7. ClassLoader loader)
  8. throws ClassNotFoundException;

上面中 ClassLoader.getCallerClassLoader 就是得到调用当前forName方法的类的类加载器

static块在什么时候执行?

  • 当调用forName(String)载入class时执行,如果调用ClassLoader.loadClass并不会执行.forName(String,false,ClassLoader)时也不会执行.
  • 如果载入Class时没有执行static块则在第一次实例化时执行.比如new ,Class.newInstance()操作
  • static块仅执行一次

各个java类由哪些classLoader加载?

  • java类可以通过实例.getClass.getClassLoader()得知
  • 接口由AppClassLoader(System ClassLoader,可以由ClassLoader.getSystemClassLoader()获得实例)载入
  • ClassLoader类由bootstrap loader载入

NoClassDefFoundError和ClassNotFoundException

  • NoClassDefFoundError:当java源文件已编译成.class文件,但是ClassLoader在运行期间在其搜寻路径load某个类时,没有找到.class文件则报这个错
  • ClassNotFoundException:试图通过一个String变量来创建一个Class类时不成功则抛出这个异常

参考:

  • 重温java之classloader体系结构(含hotswap)
  • classloader相关基础知识

其它相关 classloader:

  • [笔记]类加载器
  • 深入了解Java ClassLoader、Bytecode 、ASM、cglib
  • 解读ClassLoader

转载于:https://www.cnblogs.com/shadowofs/archive/2011/10/11/2207721.html

[转]java classLoader 体系结构相关推荐

  1. Java ClassLoader详解

    翻译原文链接 背景 Java平台旨在提供健壮,安全和可扩展的功能,以支持代码和数据的移动性.Java虚拟机(JVM)中的Java ClassLoader是实现这些目标的关键组件. JVM负责在Java ...

  2. Java内存体系结构(模型),垃圾回收和内存泄漏

    Java内存架构(Java内存模型) 上面是堆的Java内存模型以及Java虚拟机(JVM)中运行的任何Java应用程序的PermGen. 还提供了比率,以使您更好地了解如何在每种世代类型之间分配允许 ...

  3. Java IO 体系结构

    参考文章地址: http://blog.csdn.net/oracle_microsoft/article/details/2634231 Java IO体系结构看似庞大复杂,其实有规律可循,要弄清楚 ...

  4. Java异常体系结构

    一. 异常的概念和Java异常体系结构 异常是程序运行过程中出现的错误.本文主要讲授的是Java语言的异常处理.Java语言的异常处理框架,      是Java语言健壮性的一个重要体现. Java把 ...

  5. java异常体系结构详解

    java异常体系结构详解 参考文章: (1)java异常体系结构详解 (2)https://www.cnblogs.com/hainange/p/6334042.html 备忘一下.

  6. [转载] 深入了解Java ClassLoader、Bytecode 、ASM、cglib

    转载自http://www.iteye.com/topic/98178 一.Java ClassLoader 1,什么是ClassLoader  与 C 或 C++ 编写的程序不同,Java 程序并不 ...

  7. Java ClassLoader

    Java ClassLoader (1) – What is a ClassLoader? Java ClassLoader (2) – Write your own ClassLoader Java ...

  8. 深入理解Java ClassLoader及在 JavaAgent 中的应用

    转载自   深入理解Java ClassLoader及在 JavaAgent 中的应用 背景 众所周知, Java 或者其他运行在 JVM(java 虚拟机)上面的程序都需要最终便以为字节码,然后被 ...

  9. 了解和扩展Java ClassLoader

    Java ClassLoader是项目开发中Java的关键但很少使用的组件之一. 就我个人而言,我从未在任何项目中扩展ClassLoader,但是拥有自己的可以自定义Java类加载的ClassLoad ...

  10. java面试题28 牛客 下面有关java classloader说法错误的是?

    java面试题28 牛客 下面有关java classloader说法错误的是? A Java默认提供的三个ClassLoader是BootStrap ClassLoader,Extension Cl ...

最新文章

  1. 进程的用户栈和内核栈
  2. 浅谈常见的七种加密算法及实现(附代码)
  3. 在预加载新闻时,怎么去掉初始化内容的显示尴尬?
  4. Python基础——PyCharm版本——第八章、文件I/O(核心3、csv和excel解析)
  5. SystemVerilog声明的位置
  6. 手把手教你用Python求最大值和最小值
  7. 面对 10 亿数据量的挑战,如何对系统进行性能优化?
  8. 量化投资与Python
  9. 7月28日吃鸡端游服务器维护,绝地求生7月28日维护到什么时候结束
  10. 基于国土“三调”成果的自然资源开发利用和保护的综合研究
  11. Windows Server 2008 R2 下载地址
  12. 使用group by查询时报错ORDER BY clause is not in GROUP BY..this is incompatible with sql_mode=only_full_grou
  13. python检测刀具_科研一角|Python语言在人工智能加工中心机器人方面的应用
  14. nginx中的sub_filter
  15. 2019年寒假 纪中培训总结
  16. 烟雨白银坨_SAP刘梦_新浪博客
  17. 计算机专业英语词组,计算机专业英语词组.doc
  18. 自制 C++ 密码程序(第二代)
  19. 2021年总结以及2022年的计划
  20. python perl r_PHP Python Ruby Perl

热门文章

  1. 【转载好文】对char *和char []做形参的深入理解+const char*/char const*/char *const的解析
  2. java 设计模式 抽象工厂_Java设计模式----------抽象工厂模式
  3. python3.5.4安装_linux-centos系统下安装python3.5.4步骤
  4. java中charconst_C语言常量
  5. 在线工具:找到神器,助你轻松应对各种职场难题
  6. 倒排索引Inverted index
  7. 在排序数组中查找数字
  8. 技校学计算机和本科计算机,中专计算机专业学什么,中专和技校的区别​
  9. java语言没有保留结构和联合,java选择题判断题题库.doc
  10. Playing Atari with Deep Reinforcement Learning 中文 讲解3