首页 > 编程语言 >java的类加载机制

java的类加载机制

时间:2024-09-27 21:47:17浏览次数:1  
标签:初始化 java ClassLoader 该类 Java 机制 Class 加载

java的类加载机制

   Java 的类加载机制通过动态加载、内存管理、安全性和代码隔离等功能,为开发者提供了强大的支持,适应了现代应用的需求

   一、类的生命周期

   类的生命周期包括:加载、链接、初始化、使用和卸载,其中加载、链接、初始化,属于类加载的过程,我们下面仔细讲解。使用是指我们new对象进行使用,卸载指对象被垃圾回收掉了。

   如下图:

 

  二、类加载的主要步骤

  1.  Loading加载

  JVM 在该阶段的目的是将字节码从不同的数据源(可能是 class 文件、也可能是 jar 包,甚至网络)转化为二进制字节流加载到内存中,并生成一个代表该类的 java.lang.Class 对象。

  1)通过类的全限定名(包名 + 类名),获取到该类的.class文件的二进制字节流

  2)将这个二进制Å字节流所代表的静态存储结构,转化为方法区运行时的数据结构

  3)在内存中生成一个代表该类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口

  总结:加载二进制数据到内存 -> 映射成jvm能识别的结构  -> 在内存中生成class文件。

  2. 链接(Linking)

  1)验证(Verification):检查类的字节码是否符合 JVM 规范,确保安全性。

  2)准备(Preparation):为类变量分配内存,并设置默认值。

  3)解析(Resolution):将符号引用(如类名、方法名)转换为直接引用(内存地址)。

  3. 初始化(Initialization)

  执行类的静态初始化方法 <clinit>,这包括初始化静态变量和执行静态代码块。

 

  三、类加载器的类型

  类加载器的层次,如下图:

  1. 启动类加载器(Bootstrap ClassLoader)

  加载 Java 核心类库。

  2. 扩展类加载器(Extension ClassLoader)

  加载 Java 扩展库。

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

  加载用户类路径下的类。

  4. 自定义加载器

  一般情况下,以上3种加载器能满足我们日常的开发工作,不满足时,我们还可以自定义加载器。

  比如用网络加载Java类,为了保证传输中的安全性,采用了加密操作,那么以上3种加载器就无法加载这个类,这时候就需要自定义加载器。

  四、类的加载方式

  1.  命令行启动应用时候由JVM初始化加载

  2. 通过Class.forName()方法动态加载

  3. 通过ClassLoader.loadClass()方法动态加载

  代码示例:

 1 package com.pdai.jvm.classloader;
 2 public class loaderTest { 
 3         public static void main(String[] args) throws ClassNotFoundException { 
 4                 ClassLoader loader = HelloWorld.class.getClassLoader(); 
 5                 System.out.println(loader); 
 6                 //使用ClassLoader.loadClass()来加载类,不会执行初始化块 
 7                 loader.loadClass("Test2"); 
 8                 //使用Class.forName()来加载类,默认会执行初始化块 
 9 //                Class.forName("Test2"); 
10                 //使用Class.forName()来加载类,并指定ClassLoader,初始化时不执行静态块 
11 //                Class.forName("Test2", false, loader); 
12         } 
13 }
14 
15 public class Test2 { 
16         static { 
17                 System.out.println("静态初始化块执行了!"); 
18         } 
19 }

 

  五、JVM类加载机制

全盘负责,当一个类加载器负责加载某个Class时,该Class所依赖的和引用的其他Class也将由该类加载器负责载入,除非显示使用另外一个类加载器来载入父类委托,先让父类加载器试图加载该类,只有在父类加载器无法加载该类时才尝试从自己的类路径中加载该类缓存机制,缓存机制将会保证所有加载过的Class都会被缓存,当程序中需要使用某个Class时,类加载器先从缓存区寻找该Class,只有缓存区不存在,系统才会读取该类对应的二进制数据,并将其转换成Class对象,存入缓存区。这就是为什么修改了Class后,必须重启JVM,程序的修改才会生效


4. 双亲委派模型 (Parent Delegation Model)
主要用于避免类的重复加载和确保类加载的安全性。其基本思想是:一个类加载器在加载类时,首先将请求委派给它的父类加载器,只有当父类加载器无法找到该类时,子类加载器才会尝试加载。

具体描述为:
如果一个类加载器收到了类加载的请求,它首先不会自己去尝试加载这个类,而是把请求委托给父加载器去完成,依次向上,因此,所有的类加载请求最终都应该被传递到顶层的启动类加载器中,只有当父加载器在它的搜索范围中没有找到所需的类时,即无法完成该加载,子加载器才会尝试自己去加载该类


注意:

使用双亲委派模型有一个很明显的好处,那就是 Java 类随着它的类加载器一起具备了一种带有优先级的层次关系,这对于保证 Java 程序的稳定运作很重要。

上文中曾提到,如果两个类的加载器不同,即使两个类来源于同一个字节码文件,那这两个类就必定不相等——双亲委派模型能够保证同一个类最终会被特定的类加载器加载。

标签:初始化,java,ClassLoader,该类,Java,机制,Class,加载
From: https://www.cnblogs.com/hld123/p/18436634

相关文章

  • [Java手撕]生产者消费者模型
    importjava.util.LinkedList;importjava.util.Queue;importjava.util.concurrent.locks.Condition;importjava.util.concurrent.locks.ReentrantLock;publicclassMain{publicstaticfinalQueue<Integer>message=newLinkedList<>();......
  • Java中的时间序列分析:从ARIMA到LSTM的应用
    Java中的时间序列分析:从ARIMA到LSTM的应用大家好,我是微赚淘客系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在机器学习和数据科学领域,时间序列分析是一项重要的技术。它广泛应用于金融、预测分析、传感器数据处理等多个场景。在本文中,我们将重点探讨两种常用的时间......
  • 如何在Java中实现图神经网络进行社交网络分析
    如何在Java中实现图神经网络进行社交网络分析图神经网络(GraphNeuralNetworks,GNNs)是处理图数据的强大工具,尤其在社交网络分析中非常有效。社交网络本质上是一个复杂的图结构,节点代表用户,边表示用户之间的互动或关系。通过GNN,能够捕获节点的局部与全局信息,从而分析社交网......
  • Java中常用类之Object类
    Object类中的常用方法:1.hashCode方法,是对象地址值的另一种表现形式classStudent{Stringname;intage;publicStudent(){}publicStudent(Stringname,intage){this.name=name;this.age=age;}}测试类中是这样进......
  • Javascript 一题搞懂 var 变量提升 & 函数声明提升!
    前置知识:在JavaScript中,“变量提升”(Hoisting)是指在代码执行之前,变量和函数声明会被提升到其所在作用域的顶部。对于使用var关键字声明的变量,会发生变量提升现象。一、声明提升1.变量声明提升:无论var变量在代码中的何处声明,它都会被提升到其所在的函数作用域......
  • Java中浮点数运算存在的精度问题以及解决方法
    观察以下一段代码,相信小朋友都可以一眼看出答案,但是计算机给出的答案是这样吗?publicclassTestDouble{publicstaticvoidmain(Stringargs[]){System.out.println("0.05+0.01="+(0.05+0.01));System.out.println("1.0-0.42="+(1.0-0.42));System.out.pr......
  • +在Java中的使用
    阅读以下代码,输出结果是什么?`publicclassTest{publicstaticvoidmain(String[]args){intX=100;intY=200;System.out.println("X+Y="+X+Y);System.out.println(X+Y+"=X+Y");}}`运行结果:为什么会有这样的输出结......
  • 类中静态代码块、静态属性加载顺序
     1、如果静态属性在静态代码块前面classFoo{publicFoo(){System.out.println("我是Example的静态属性foo");System.out.println("未修改的静态属性值为====>"+Example.staticVariable);Example.staticVariable=2;......
  • 基于Java+Springboot+Vue开发的健身房管理系统源码+参考文章1.3万字
    项目简介该项目是基于Java+Springboot+Vue开发的健身房管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的健身房管理系统项目,大学生可以在实践中学习和提升......
  • 基于Java+Springboot+Vue开发的家具管理系统源码+开发文档
    项目简介该项目是基于Java+Springboot+Vue开发的家具管理系统(前后端分离),这是一项为大学生课程设计作业而开发的项目。该系统旨在帮助大学生学习并掌握Java编程技能,同时锻炼他们的项目设计与开发能力。通过学习基于Java的家具管理系统项目,大学生可以在实践中学习和提升自己......