补充(非书中):

  Java 源程序(.java 文件)在经过 Java 编译器编译之后就被转换成 Java 字节代码(.class 文件)。类加载器负责读取Java字节代码,并转换成 java.lang.Class类的一个实例。每个这样的实例用来表示一个Java 类。通过此实例的 newInstance()方法就可以创建出该类的一个对象。

Java 中的类加载器大致可以分成两类:

一类是系统提供的:

  • 引导类加载器(bootstrapclass loader):它用来加载 Java 的核心库,是用原生代码而不是java来实现的,并不继承自java.lang.ClassLoader,除此之外基本上所有的类加载器都是java.lang.ClassLoader类的一个实例。
  • 扩展类加载器(extensionsclass loader):它用来加载 Java 的扩展库。Java 虚拟机的实现会提供一个扩展库目录(一般为%JRE_HOME%/lib/ext)。该类加载器在此目录里面查找并加载 Java 类。
  • 系统类加载器(systemclass loader或 App class loader):它根据当前Java 应用的类路径(CLASSPATH)来加载 Java 类。一般来说,Java 应用的类都是由它来完成加载的。可以通过 ClassLoader.getSystemClassLoader() 来获取它。

另外一类则是由 Java 应用开发人员编写的:

  • 开发人员可以通过继承java.lang.ClassLoader 类的方式实现自己的类加载器,以满足一些特殊的需求

 classLoader是类加载器,负责将Class加载到JVM中,还有一个作用是审查每个类由谁加载,它是一种父优先的等级加载机制。

还有一个任务是,将class字节码重新解析成JVM统一要求的对象格式。

加载类过程:

  假如loader2的parent为loader1,loader1的parent为system class loader。假设loader2被要求装载类MyClass,在parent delegation模型下,loader2首先请求loader1代为装载,loader1再请求系统类装载器去装载MyClass。若系统装载器能成功装载,则将MyClass所对应的Class对象的reference返回给loader1,loader1再将reference返回给loader2,从而成功将类MyClass装载进虚拟机。若系统类装载器不能装载MyClass,loader1会尝试装载MyClass,若loader1也不能成功装载,loader2会尝试装载。若所有的parent及loader2本身都不能装载,则装载失败。

6.1 ClassLoader类结构分析

 defineClass(byte[], int, int): 将byte字节流解析成JVM能识别的class对象。

 findClass(String):

 loadClass(String): 获取class对象。

 resolveClass(Class<?>):

ClassLoader是抽象类,有很多子类,如果我们要实现自己的ClassLoader,一般会继承URLClassLoader, 做修改就好了。

6.2 ClassLoader的等级加载机制

JVM提供三层ClassLoader,这三层ClassLoader可以分为两种类型

(1)Bootstrap ClassLoader: 加载JVM自身工作需要的类,完全由JVM自己控制,别人访问不到这个类,没有高一级的加载器,也没有子加载器。

(2)ExtClassLoader:

(3)AppClassLoader:

如果我们要实现自己的类加载器,不管是直接实现抽象类ClassLoader,还是继承URLClassLoader,或其他子类,它的父加载器都是AppClassLoader。

ExtClassLoader和AppClassLoader都继承了URLClassLoader类。

  

JVM加载class文件到内存有两种方式:

隐式加载:不在代码中调用ClassLoader来加载需要的类,而是通过JVM来自动加载需要的类到内存的方式。比如当在类中继承或引用某个类时,JVM发现其不在内存中,就会自动加载到内存。

显示加载:通过ClassLoader类来加载一个类的方式,this.getClass.getClassLoader().loadClass()或者Class.forName(). 或者我们自己实现的ClassLoader的findClass()方法。

6.3 如何加载class文件

       三个步骤:

    1 找到.class文件并把这个文件包含的字节码加载到内存。

2 字节码校验,Class类数据结构分析以及相应的内存分配和最后的符号表链接

    3 类中静态属性和初始化赋值,已经静态块的执行等。  

  6.3.1 加载字节码到内存

    URLClassLoader如何实现findclass()的,URLCclassLoader中通过一个URLClassPath类帮助取得要加载的class文件字节流,而这个URLClasspath定义了到哪里去找这个

    class文件,如果找到,再读它的byte字节流,通过definClass()来创建类对象。根据路径的不同(是文件还是jar包)来创建FIleLoader或JarLoader.

  6.3.2 验证与解析

    字节码验证,验证格式正确,行为正确。

    类准备,这个阶段准备代表每个类中定义的字段,方法和实现接口所必须的数据结构。

    解析,装入类所引用的其他所有类。

  6.3.3 初始化class对象

    执行静态初始化器,静态字段会为初始化为默认值。

6.4 常见加载类错误分析

    6.4.1 ClassNotFoundException

  显示加载类三种方法:

    Class.forName();

    ClassLoader.loadClass()

    ClassLoader.findSystemClass()   

  6.4.2 NoClassDefFoundError

    类可能没加包名。

  6.4.3 UnsatisfiedLinkError

    可能是误删了lib文件

  6.4.4 ClassCastExcetption

    JVM做类型转换的检查规则:

  • 普通对象,对象必须是目标类的实例或是目标类子类的实例。如果目标类是接口,那么可以把它当做实现了该接口的一个子类。
  •  对于数组类型,目标类型必须是数组类型或java.lang,Object, java.lang,Clonble, java.io.serializable

如果不满足上面的规则,JVM就会报错:

要想避免这个错误 有两种方式:

      容器类型中显示地指明容器对象类型,

      通过instanceof检查是不是目标类型,然后在强转。

  6.4.5 ExceptinInInitializerError

6.5 常用的ClassLoader分析

  这里分析了servlet的ClassLoader

6.6 如何实现自己的ClassLoader

  为什么要实现自己的classLoader

    在自己的路径下查找自定义的class文件,不一定在classPath下面。

    对我们的类做特殊处理,比如加密传输类在网络之间。这就需要在加载到JVM之前先解密。

    可以定义类的实现机制,实现热部署。

  6.6.1 加载自定义路径下的class文件

  6.6.2 加载自定义格式的class文件

6.7 实现类的热部署

  JVM在加载类之前会检查类是否已经被加载过,也就是要调用findLoadedClass()方法查看是否能返回类实例

JVM表示两个类是否是同一个类有两个条件:

    一是看类的完整类名是否一样。

    二是看加载这个类的ClassLoader是否是同一个(是指ClassLoader实例是否是同一个)。

实现热部署:可以用ClassLoader的两个实例加载同名的类。

6.8 java应不应该动态加载类

  JAVA修改一个类,必须重启JVM。

第六章 深入分析ClassLoader工作机制的更多相关文章

  1. 《精通Spring4.X企业应用开发实战》读后感第六章(内部工作机制、BeanDefinition、InstantiationStrategy、BeanWrapper)

  2. 深入理解ClassLoader工作机制(jdk1.8)

    ClassLoader 顾名思义就是类加载器,ClassLoader 作用: 负责将 Class 加载到 JVM 中    审查每个类由谁加载(父优先的等级加载机制)    将 Class 字节码重新 ...

  3. Android群英传笔记——第六章:Android绘图机制与处理技巧

    Android群英传笔记--第六章:Android绘图机制与处理技巧 一直在情调,时间都是可以自己调节的,不然世界上哪有这么多牛X的人 今天就开始读第六章了,算日子也刚好一个月了,一个月就读一半,这效 ...

  4. 理解ClassLoader工作机制

    package com.ioc; public class Test { public static void main(String[] args) throws ClassNotFoundExce ...

  5. Java Web 深入分析(5) Java ClassLoader 工作机制

    Classloader 有3个作用 将class加载到JVM中去 审查每个类由谁去加载,是一种父优先的等级加载 把Class字节码统一编译成JVM统一要求的对象格式 ClassLoader的等级加载机 ...

  6. ClassLoader工作机制

    阅读目录 一.ClassLoader概念 二.JVM平台提供三层classLoader 三.JVM加载class文件到内存有两种方式 四.ClassLoader加载类的过程 五.自定义类加载器 六.实 ...

  7. Java Web ClassLoader工作机制

    一.ClassLoader的作用: 1.类加载机制:父优先的等级加载机制 2.类加载过程 3.将Class字节码重新解析成JVM统一要求的对象格式 二.ClassLoader常用方法 1.define ...

  8. ClassLoader 工作机制

    ClassLoader 采用上级委托接待机制加载 class JVM 平台提供三层 ClassLoader 1.Bootstrap ClassLoader:主要加载 JVM 自身工作需要的类 2.Ex ...

  9. 第2章 深入分析java I/O的工作机制(上)

    java的I/O操作类在包java.io下,大致分成4组: 所有文件的存储都是字节(byte)的储存,在磁盘上保留的并不是文件的字符而是先把字符编码成字节,再存储这些字节到磁盘.在读取文件时,也是一个 ...

随机推荐

  1. oracle,查看锁表

    (1)锁表查询的代码有以下的形式:select count(*) from v$locked_object;select * from v$locked_object;(2)查看哪个表被锁select ...

  2. python twisted教程[资料]

    python twisted教程 一,异步编程 http://www.douban.com/note/232200511/   python twisted教程 二:缓慢的诗 http://www.d ...

  3. java Graphics2d消除锯齿,使字体平滑显示

    Java 2D API 提供的文本处理功能进行美化.Java 2D API 的文本功能包括: 使用抗锯齿处理和微调(hinting)以达到更好的输出质量 可以使用系统安装的所有字体 可以将对图形对象的 ...

  4. web项目在iis配置好后不能正确访问问题集锦,以及IIS常规设置

    6.IIS配置好,项目无法访问,注意项目对应的应用程序池的net版本是否正确,是否集成(一般都是集成,很少是经典) 本项目用的4.0,可IIS默认程序池为2.0,将2.0改为4.0就行.   7.HT ...

  5. java中int i 会出现i+1i吗

    Java中int是32,范围是-2147483648到2147483647 所以i+1 < i 或者 i-1 > i是会出现的. int i=(int) Math.pow(2, 32); ...

  6. softmax回归(理论部分解释)

    前面我们已经说了logistic回归,训练样本是,(且这里的是d维,下面模型公式的x是d+1维,其中多出来的一维是截距横为1,这里的y=±1也可以写成其他的值,这个无所谓不影响模型,只要是两类问题就可 ...

  7. Django restfull规范

    一. 什么是RESTful REST与技术无关,代表的是一种软件架构风格,REST是Representational State Transfer的简称,中文翻译为“表征状态转移” REST从资源的角 ...

  8. Myeclipse快捷键的设置以及默认的编码格式

    设置默认的编码格式

  9. react-redux: async promise

    1.the simple sample action: 事实上,只是返回个一个至少包含type的对象{ },用于reducer接收. import {RECEIVE_DATA} from " ...

  10. [Hive]HiveServer2配置

    HiveServer2(HS2)是一个服务器接口,能使远程客户端执行Hive查询,并且可以检索结果.HiveServer2是HiveServer1的改进版,HiveServer1已经被废弃.HiveS ...