三、Java日常积累:Java类的加载机制

类的加载机制📽

类加载过程:

类从被加载到jvm内存中开始到卸载出内存为止,整个生命周期:

加载 -> 链接(验证 -> 准备 -> 解析) -  > 初始化 -> 使用 -> 卸载,开始顺序如图所示:

1.类加载过程包括加载、链接(验证、准备、解析)、初始化:

  1. 其中加载、验证、准备、初始化是确定的。
  2. 解析阶段可以再初始化阶段之后,这是为了支持java语言的运行时绑定(也称之为动态绑定)。
  3. 这里的几个阶段是按照顺序开始,而不是按照顺序进行或完成,因为这些阶段通常都是互相交叉呼和进行,通常在一个工程中调用或激活另一个过程。

2.java中的绑定:

  1. 绑定:指的是把一个方法的调用和方法所在的类(方法主体)关联起来,分为静态绑定和动态绑定。
  2. 静态绑定:前期绑定;程序执行前方法已经绑定,由编译器实现,针对java,简单的理解为程序编译期的绑定,java当中的方法只有final、static、private和构造方法是静态绑定的。
  3. 动态绑定:晚期绑定,运行时绑定;在运行时根据具体对象类型进行绑定;java中几乎所有的方法都是动态绑定;

加载阶段:

1.加载:
是加载过程中的第一个阶段,这个阶段jvm需要完成三件事:

  1. 通过类的全限定名获取其.class文件的二进制字节流。
  2. 将这个二进制字节流所代表的静态存储结构转化为方法区的运行时数据结构。
  3. 在java**堆(包括static常量区)中生成一个代表这个类的java.lang.Class对象,作为对方法区(特殊的堆)**中这些数据的访问入口。

2.二级制字节流获取方式:

  1. 从.class文件中获取。
  2. 从jar包中获取。
  3. 从网络中(Applet)获取。
  4. 从其他文件生成(比如jsp)。

3.加载阶段的可控性相对较强:
准确的说是获取二进制字节流的动作是可控性最强的阶段,因为开发人员既可以使用系统提供的类加载器、也可以使用自定义的类加载器来完成加载。

4.加载阶段完成:
加载阶段完成后,虚拟机外部的二进制字节流就按照jvm所需的格式存储在方法区中,而且在java堆中创建一个java.lang.Class类的对象,这样便可以通过改对象访问中的这些数据。

5.类加载器:处理、从jvm的角度看,只存在两种不同的类加载器:

  1. 启动类加载器:使用c++实现,是jvm的一部分。
  2. 其他类加载器:这些类加载器都由java语言实现,独立于jvm之外,并且全部继承自抽象类java.lang.ClassLoader,这些类加载器需要由启动类加载器加载到内存中之后才能去加载类。

6. 站在开发人员的角度,类加载器大致可以分为3类:

  1. 启动类加载器:BootStrap ClassLoader,跟上面相同,负责加载存放在jdk\jre\lib(安装目录),或者被-XbootClasspath参数指定的路径,并且能被jvm识别的类库(rt.jar和java.*的类),启动类加载器无法直接被java程序引用,classpath路径:System.getProperty("sun.boot.class.path")
  2. 扩展类加载器:Extension ClassLoader,该加载器由sun.misc.Launcher$ExtClassLoader实现,负责加载jdk\jre\lib\ext目录,或者有java.ext.dirs系统变量指定的路径中的所有类库(如javax.*开头的类),可以直接被java程序引用。classpath路径:System.getProperty("java.ext.dirs")
  3. 应用程序类加载器:Application ClassLoader,该类加载器由sun.misc.Launcher$AppClassLoader实现,负责加载用户类路径(CLASSPATH)所指定的类,可以直接被java程序引用,如果应用程序中没有自定义多自己的类加载器,一般情况下就是程序中默认的类加载器。classpath路径:System.getProperty("java.class.path")

应用程序都是由这3种类加载器相互配合加载的,还可以加入自定义的class loader。因为jvm自带的ClassLoader只懂得从本地文件系统中加载标准的java class文件,自定的class loader,可以做到以下几点:

  1. 执行非置信代码之前,自动验证数字签名。
  2. 动态创建符合用户特定需要的定制化构建类。
  3. 从特定的场所取得java class,例如数据库、网络等等。
    使用Applet的时候就用到了特定的class loader,因为这个时候需要从网络上加载java class,并且要检查安全信息,应用服务器大多都使用了自定义的class loader技术

这些类加载器的层次关系如下图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WMsEdN0C-1592643140627)(file:///D:/softWareInstall/WizNote/mynote/images/loader.png “类加载器层次关系”)]
双亲委派模型:
这种层次关系称之为双亲委派模型,每一层类加载器上面的类加载器叫做父加载器,但是他们之间的父子关系不是通过继承实现,而是使用组合关系来复用父类加载器中的代码。该模型在jdk1.2引入并广泛引用于几乎所有的java程序中,不是一个强制性约束,是java设计者推荐给开发者的一种类加载模式。
双亲委派模型工作流程:
类加载器收到类加载请求,先把请求委派给父加载器完成,依次向上,因此所有类加载的请求最终都被传递到顶层的启动类加载器中,只有父加载器在他的搜索范围内没有找到所需的类,子加载器才会尝试自己去加载该类。一句话,自底向上请求加载,自顶向下尝试加载
双亲委派模型好处:
java随着他的类加载器一起具备了一种带有优先级的层次关系,对于java程序稳定运行很重要,例如java.lang.Object存放在jdk\jre\lib下的rt.jar中,无论是哪个类加载器加载此类,最终都会委派给启动加载器加载,这就保证Object类在程序中的各种类加载器中都是同一个类。
###连接–验证阶段:
验证的目的为了确保Class文件中字节流包含的信息符合当前jvm的要求,保证不会危害jvm的安全;不同jvm对类验证的实现有些不同,大致会完成四个

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值