常见类加载器:BootstrapClassLoader/ExtClassLoader/AppClassLoader/URLClassLoader/WebappClassLoader。html
BootstrapClassLoader(启动类加载器):主要加载JVM自身工做须要的类,彻底由JVM本身控制;它是全部类加载器的父加载器,位于jre/lib/rt.jar。java
ExtClassLoader(扩展类加载器):它既装载除了基本的Java API之外的扩展类,也负责装载其余的安全扩展功能;位于System.getProperty("java.ext.dirs")指向的目录。bootstrap
AppClassLoader(系统类加载器):负责加载用户在$CLASSPATH里指定的类,位于System.getProperty("java.class.path")。安全
User-defined ClassLoader(用户自定义类加载器):直接用代码实现的类加载器,如:WebappClassLoader。app
类是如何被加载的? 它们使用双亲委派的模型来加载;基于三个机制:委托、可见性和单一性。this
委托:当一个类加载和初始化的时候,类仅在有须要加载的时候被加载。首先加载这个类的请求由AppClassLoader委托给它的父类加载器ExtClassLoader,而后再委托给BootstrapClassLoader。BootstrapClassLoader会先看看rt.jar中有没有这个类,若是并无这个类,就把这个请求返回到ExtClassLoader,它会查看jre/lib/ext目录下有没有这个类,若是这个类被ExtClassLoader找到了,那么它将被加载,而AppClassLoader不会加载这个类;而若是这个类没有被ExtClassLoader找到,那么再由AppClassLoader从classpath中寻找。spa
可见性:子类加载器能够看到父类加载器加载的类,而反之则不行。.net
单一性:父加载器加载过的类不能被子加载器加载第二次。htm
class的加载方式?对象
隐式加载:不经过调用ClassLoader来加载须要的类,而是经过JVM自动加载所需的类到内存。如,继承与类引用。
显示加载:经过ClassLoader类来加载类的方式。如,this.getClass().getClassLoader().loadClass()/Class.forName()/自定义的类加载器的findClass()。
Class.forName(),ClassLoader.loadClass()的区别
http://blog.csdn.net/qq_27093465/article/details/52262340
自定义类加载器?
本身定义的类加载器通常继承ClassLoader/URLClassLoader。
通常只须要重写findClass()方法;
同一个类若是被两个类加载器加载,那么JVM不认为使相同的类;
检查被请求的类是否已经被加载到命名空间,若是已被加载,则直接返回。
若是想打破双亲委派模型,那么就重写整个loadClass方法
https://www.cnblogs.com/szlbm/p/5504631.html
JDK中的ClassLoader实现的:
先先查找.class是否被加载过,若是.class文件没有被加载过,那么会去找加载器的父加载器。
父加载器开始尝试加载.class文件,加载成功就返回一个java.lang.Class,加载不成功就抛出一个ClassNotFoundException,给子加载器去加载。
双亲委派机制
一、类的加载过程采用委托模式实现
二、每一个 ClassLoader 都有一个父加载器。
三、类加载器在加载类以前会先递归的去尝试使用父加载器加载。
四、虚拟机有一个内建的启动类加载器(bootstrap ClassLoader),该加载器没有父加载器,可是能够做为其余加载器的父加载器。
双亲委派机制能很好地解决类加载的统一性问题。
JVM在断定两个class是否相同时,不只要判断两个类名是否相同,并且要判断是否由同一个类加载器实例加载的。只有二者同时知足的状况下,JVM才认为这两个class是相同的。
对一个 Class 对象来讲,若是类加载器不一样,即使是同一个字节码文件,生成的 Class 对象也是不等的。也就是说,类加载器至关于 Class 对象的一个命名空间。
双亲委派机制则保证了基类都由相同的类加载器加载,这样就避免了同一个字节码文件被屡次加载生成不一样的 Class 对象的问题。
但双亲委派机制仅仅是Java 规范所推荐的一种实现方式,它并非强制性的要求。近年来,不少热部署的技术都已不遵循这一规则,如 OSGi 技术就采用了一种网状的结构,而非双亲委派机制。
http://www.cnblogs.com/paddix/p/5268559.html
classloader加载一个类的过程分为4步:
第一步,从某个地方获得咱们想要的字节码二进制流;
第二步,读入字节码流并转化为Class;
第三步,连接;
第四步,初始化。
ClassLoader 提供了另外一个方法 findClass 来完成第一步,
而后调用ClassLoader提供的defineClass来完成第二步,
ClassLoader提供了resolveClass方法完成第三步连接的工做
https://mp.weixin.qq.com/s/qHTXwS4BdI2gKwPzQK-D6g
Class.forName和ClassLoader.loadClass区别:
第一,ClassLoader.loadClass能够显式指定装载class的ClassLoader,可是Class.forName就不行了,他会默认使用调用类的ClassLoader来装载class。
第二,ClassLoader.loadClass仅仅加载class进来,可是不会初始化类,而Class.forName不只会加载class并且还会初始化类。
https://blog.csdn.net/liweisnake/article/details/8857744
https://blog.csdn.net/u011202334/article/details/51497998
http://blog.csdn.net/xyang81/article/details/7292380#10006-weixin-1-52626-6b3bffd01fdde4900130bc5a2751b6d1