众所周知,java是编译型的语言,写的是java文件,最后运行的是class文件,class文件是运行在JVM之中的,这时候就有一个问题,JVM如何装载class文件的?是经过ClassLoader来进行的,这里作一下笔记,由于发现原做者写的很好《深刻分析java web 技术内幕》。java
ClassLoader的结构分析 web
ClassLoader是一个抽象类,他有不少子类,JVM默认有几个实现类,固然咱们也能够本身继承ClassLoader。安全
一、defineClass:将byte字节转换为JVM可以识别的Class对象,这样就意味着能够是class文件也但是是网络上的字节流了;网络
二、defineClass一般和findClass一块儿使用,findClass的做用是取得要加载的类的字节码;数据结构
三、若是想在类被加载到JVM的时候就被连接,能够调用resolveClass来完成;this
四、若是不想自定义加载类的规则,也没有复杂的逻辑,能够经过this.getClass().getClassLoader().loadClass("") 来进行加载;spa
ClassLoader中的几个实现类 对象
一、Bootstrap ClassLoader 这个是JVM加载自身工做须要的类,彻底由JVM本身来控制,外部没法访问到这个;blog
二、ExtClassLoader比较特殊的,服务的特定目标在System.getProperty("java.ext.dirs");继承
三、AppClassLoader,父类是ExtClassLoader,"java.class.path"中的类均可以被这个类加载器加载;
四、URLClassLoader,通常这个类帮咱们实现了大部分的工做,自定义能够继承这个类,这样仅仅在须要的地方作修改就好了;
JVM加载class文件到内存的方式
一、显示加载:不经过代码里的ClassLoader调用,而是JVM来自动加载类到内存中的方式;
1.一、经过Class中的forName;
1.二、经过ClassLoader中的loadClass
1.三、经过ClasLoader中的findSystemClass
二、隐身加载:经过代码中ClassLoader来加载的方式;
如何加载class文件
一、找到.class文件,并把文件中包含的byte加载到内存中
二、验证和解析
2.一、字节码验证,确保格式正确和行为正确
2.二、类准备,类中定义的字段、方法和实现接口锁必须的数据结构
2.三、解析,装入类所引用的其余全部类,如父类、字段、方法签名、方法中使用的本地变量等
三、静态属性和初始化赋值,以及静态块的执行等
关于类加载过程当中的几种常见异常
一、ClassNotFoundException
JVM要加载指定的文件的字节码到内存中,可是并无发现这个文件的字节码。检查方法就是在classpath中看看是否有指定文件存在。
二、NoClassDefFoundError
JVM规范中这个异常出现的状况是使用new 关键字、属性引用类、实现接口、继承类,若是不存在,会报这个异常。
三、ClassCastException
对于普通对象,对象必须是目标类的实例或者目标类的子类的实例,若是目标类是接口,那么会把他当作实现了该接口的一个子类。
有哪些须要自定义ClassLoader的状况?
一、在自定义的路径下查找自定义的classs文件,须要的文件并非classpath下面的;
二、对于加载的类作特殊的处理,例如网络传输的安全性等;
三、能够定义类的失效机制,例如检查到文件被修改,则从新加载,从而实现类的热部署;
http://iamzhongyong.iteye.com/blog/2091549