类加载器概述:

  java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制.JVM中用来完成上述功能的具体实现就是类加载器.类加载器读取.class字节码文件将其转换成java.lang.Class类的一个实例.每个实例用来表示一个java类.通过该实例的newInstance()方法可以创建出一个该类的对象.

类的生命周期:

  类从加载到虚拟机内存到被从内存中释放,经历的生命周期如下:

加载:"加载"是"类加载"过程的一个阶段,此阶段完成的功能是:

  通过类的全限定名来获取定义此类的二进制字节流

  将此二进制字节流所代表的静态存储结构转化成方法区的运行时数据结构

  在内存中生成代表此类的java.lang.Class对象,作为该类访问入口.

验证:连接阶段第一步.验证的目的是确保Class文件的字节流中信息符合虚拟机的要求,不会危害虚拟机安全,使得虚拟机免受恶意代码的攻击.大致完成以下四个校验动作:

  文件格式验证

  源数据验证

  字节码验证

  符号引用验证

准备:连接阶段第二步,正式为类变量分配内存并设置变量的初始值.(仅包含类变量,不包含实例变量).  

解析:连接阶段第三步,虚拟机将常量池中的符号引用替换为直接引用,解析动作主要针对类或接口,字段,类方法,方法类型等等..

初始化:类的初始化是类加载过程的最后一步,在该阶段,才真正意义上的开始执行类中定义的java程序代码.该阶段会执行类构造器.

使用:使用该类所提供的功能.

卸载:从内存中释放.

获取Class文件途径:

  java类可以动态被加载到内存,这是java的一大特点,也称为运行时绑定,或动态绑定.

     1.从ZIP包中读取,很常见,最终成为日后JAR,WAR,EAR格式的基础.

     2.从网络中获取,这种场景典型的就是Applet.

     3.运行时计算生成,典型的情景就是java动态代理技术.

     4.从其他文件中生成,典型场景是JSP应用,即由JSP文件生成对应的Class类.

java.lang.ClassLoader类概述:

  中文文档中对ClassLoader类的定义如下:

   

   从文档中对ClassLoader类的介绍可以总结出这个类的作用就是根据一个指定的类的全限定名,找到对应的Class字节码文件,然后加载它转化成一个java.lang.Class类的一个实例.

类加载器的划分:

   大部分java程序会使用以下3中系统提供的类加载器:

   启动类加载器(Bootstrap ClassLoader):

    这个类加载器负责将<JAVA_HOME>\lib目录下的类库加载到虚拟机内存中,用来加载java的核心库,此类加载器并不继承于java.lang.ClassLoader,不能被java程序直接调用,代码是使用C++编写的.是虚拟机自身的一部分.

   扩展类加载器(Extendsion ClassLoader):
   
 这个类加载器负责加载<JAVA_HOME>\lib\ext目录下的类库,用来加载java的扩展库,开发者可以直接使用这个类加载器.

   应用程序类加载器(Application ClassLoader):

    这个类加载器负责加载用户类路径(CLASSPATH)下的类库,一般我们编写的java类都是由这个类加载器加载,这个类加载器是CLassLoader中的getSystemClassLoader()方法的返回值,所以也称为系统类加载器.一般情况下这就是系统默认的类加载器.

  除此之外,我们还可以加入自己定义的类加载器,以满足特殊的需求,需要继承java.lang.ClassLoader类.

  类加载器之间的层次关系如下图:

   

使用代码观察一下类加载器:

package com.wang.test;

public class TestClassLoader {

    public static void main(String[] args) {
ClassLoader loader = TestClassLoader.class.getClassLoader();
System.out.println(loader.toString());
System.out.println(loader.getParent().toString());
System.out.println(loader.getParent().getParent());
}
}

观察打印结果:

sun.misc.Launcher$AppClassLoader@500c05c2
sun.misc.Launcher$ExtClassLoader@454e2c9c
null

  第一行打印的是应用程序类加载器(默认加载器),第二行打印的是其父类加载器,扩展类加载器,按照我们的想法第三行应该打印启动类加载器的,这里却返回的null,原因是getParent(),返回时null的话,就默认使用启动类加载器作为父加载器.

类加载器的双亲委派模型:

  双亲委派模型是一种组织类加载器之间关系的一种规范,他的工作原理是:如果一个类加载器收到了类加载的请求,它不会自己去尝试加载这个类,而是把这个请求委派给父类加载器去完成,这样层层递进,最终所有的加载请求都被传到最顶层的启动类加载器中,只有当父类加载器无法完成这个加载请求(它的搜索范围内没有找到所需的类)时,才会交给子类加载器去尝试加载.

  这样的好处是:java类随着它的类加载器一起具备了带有优先级的层次关系.这是十分必要的,比如java.langObject,它存放在\jre\lib\rt.jar中,它是所有java类的父类,因此无论哪个类加载都要加载这个类,最终所有的加载请求都汇总到顶层的启动类加载器中,因此Object类会由启动类加载器来加载,所以加载的都是同一个类,如果不使用双亲委派模型,由各个类加载器自行去加载的话,系统中就会出现不止一个Object类,应用程序就会全乱了.

Class.forname()与ClassLoader.loadClass():

  Class.forname():是一个静态方法,最常用的是Class.forname(String className);根据传入的类的全限定名返回一个Class对象.该方法在将Class文件加载到内存的同时,会执行类的初始化.

  如: Class.forName("com.wang.HelloWorld");

  ClassLoader.loadClass():这是一个实例方法,需要一个ClassLoader对象来调用该方法,该方法将Class文件加载到内存时,并不会执行类的初始化,直到这个类第一次使用时才进行初始化.该方法因为需要得到一个ClassLoader对象,所以可以根据需要指定使用哪个类加载器.

  如:ClassLoader cl=.......;cl.loadClass("com.wang.HelloWorld");

深入理解Java类加载器(1)的更多相关文章

  1. 深入理解Java类加载器(ClassLoader)

    深入理解Java类加载器(ClassLoader) Java学习记录--委派模型与类加载器 关于Java类加载双亲委派机制的思考(附一道面试题) 真正理解线程上下文类加载器(多案例分析) [jvm解析 ...

  2. 深入理解Java类加载器(ClassLoader) (转)

    转自: http://blog.csdn.net/javazejian/article/details/73413292 关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Ja ...

  3. 深入理解Java类加载器(一):Java类加载原理解析

    摘要: 每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这个异常背后涉及到的是Java技术体系中的类加载机制.本文简述了JVM三种预定义类加载器,即 ...

  4. 深入理解Java类加载器(二):线程上下文类加载器

    摘要: 博文<深入理解Java类加载器(一):Java类加载原理解析>提到的类加载器的双亲委派模型并不是一个强制性的约束模型,而是Java设计者推荐给开发者的类加载器的实现方式.在Java ...

  5. java笔记--理解java类加载器以及ClassLoader类

    类加载器概述: java类的加载是由虚拟机来完成的,虚拟机把描述类的Class文件加载到内存,并对数据进行校验,解析和初始化,最终形成能被java虚拟机直接使用的java类型,这就是虚拟机的类加载机制 ...

  6. 深入理解Java类加载器(1):Java类加载原理解析

    1 基本信息 每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...

  7. 转载 深入理解java类加载器

    1 基本信息 每个开发人员对java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...

  8. 深入理解Java类加载器(2)

    1 基本信息 每个开发人员对Java.lang.ClassNotFoundExcetpion这个异常肯定都不陌生,这背后就涉及到了java技术体系中的类加载.Java的类加载机制是技术体系中比较核心的 ...

  9. 深入理解Java类加载器(3)

    5.2 网络类加载器 下面将通过一个网络类加载器来说明如何通过类加载器来实现组件的动态更新.即基本的场景是:Java 字节代码(.class)文件存放在服务器上,客户端通过网络的方式获取字节代码并执行 ...

随机推荐

  1. nginx如何做到TCP的负载均衡

    原文:https://blog.csdn.net/u011218159/article/details/50966861   TCP 的 负载均衡   这个片段描述了如何通过nginx plus进行负 ...

  2. PostgreSQL的hook机制初步学习

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面:PostgreSQL内部结构与源代码研究索引页    回到顶级页面:PostgreSQL索引页 本文的目的一是为了备忘,二是为了抛砖引玉,希望 ...

  3. [2016北京集训试题15]项链-[FFT]

    Description Solution 设y[i+k]=y[i]+n. 由于我们要最优解,则假如将x[i]和y[σ[i]]连线的话,线是一定不会交叉的. 所以,$ans=\sum (x_{i}-y_ ...

  4. CSS快速入门-定位(position)

    一.概述 CSS 定位 (Positioning) 属性允许你对元素进行定位. 定位的基本思想很简单,它允许你定义元素框相对于其正常位置应该出现的位置,或者相对于父元素.另一个元素甚至浏览器窗口本身的 ...

  5. Model详解

    一.数据库操作 Model操作: 创建数据库表结构(建表) 操作数据库表(增删改查) 做一部分的验证(验证) a.建表 1.表字段 AutoField(Field) - int自增列,必须填入参数 p ...

  6. 5 行 Python 代码调用电脑摄像头

    前提: 确保 python 中安装了 opencv-python 模块.如果没有安装,可以参考:https://pypi.org/project/opencv-python/ 进行安装.话不多少,直接 ...

  7. 手把手教你测微信小程序

    WeTest 导读 在小程序持续大量爆发的形势下,现在已经成为了各平台竞争的战略布局重点.至今年2月,月活超500万的微信小程序已经达到237个,其中个人开发占比高达2成.因小程序的开发门槛低.传播快 ...

  8. $.post(url,[data],[callback],'json')

    $.post(url,[data],[callback],'json')这个写法来做到用post方法传递数据,并取加回json型数据.如果我要取回的数据类型是xml的,就可以写成$.post(url, ...

  9. 动态加载与插件系统的初步实现(三):WinForm示例

    代码文件在此Download,本文章围绕前文所述默认AppDomain.插件容器AppDomain两个域及IPlugin.PluginProvider.PluginProxy3个类的使用与变化进行. ...

  10. CentOS7.2下配置SOCKS5代理

    SOCKS介绍: 1.这里只做简单介绍.         SOCKS5 是一个代理协议,它在使用TCP/IP协议通讯的前端机器和服务器机器之间扮演一个中介角色,使得内部网中的前端机器变得能够访问Int ...