首页 > 其他 > 详细

类的加载过程

时间:2021-01-04 23:23:20      阅读:32      评论:0      收藏:0      [点我收藏+]

一、类的加载阶段

  类的加载阶段,其实就是将class字节码文件中的二进制数据读取到内存之中,然后将文件所代表的静态存储结构,转换为方法区中运行时的数据结构,并且在堆内存中生成一个该类的java.lang.Class对象,作为访问方法区数据结构的入口。

而在同一个类加载器下,无论一个类被加载多少次,堆内存里面的Class对象都只有唯一 的一个。

  而加载的方式也不仅仅是字节码文件或者说字节流的形式,还有我们都知道的动态代理,可以运行时动态生成字节码的字节流,从jar包中获取字节流等等,加载阶段不局限一种形式。

 

二、类的连接阶段

1、验证

  验证字节流的信息是否符合JVM的规范,保证不会出现危害JVM的代码。一般就是验证这个文件的格式,也就是头部信息是不是class文件,还有版本号,用高版本编译的文件是不能被低版本的兼容的;验证元数据的继承等进行语义分析是否合法;验证代码的控制流程等;还有就是符号引用的验证。

2、准备

  经过了验证之后,就会开始对该类对象的变量分配内存,并且设置初始值,而类变量的内存是分配在方法区中的,不同于实例变量。

3、解析

  这个阶段,其实就是把部分符号引用替换成直接引用。比如说

1 public class Tes1{
2     static Simple simple;
3 
4     public static void main(String[] args) {
5         System.out.println(simple);
6     }
7 }

在方法中引用了simple,那么在解析阶段就会在常量池找simple的符号引用,然后对simple加载,然后符号引用就会转换成直接引用,也就是simple的内存地址。

三、类的初始化阶段

  在这个阶段中,主要就是执行<clinit>()方法,在方法中,所有的类变量都会被赋予正确的值,以及执行静态语句块。

  <clinit>()这个方法是在编译阶段,由编译器自动生成在class文件中的,方法里面的执行顺序与源代码中的书写顺序是一致的!!!也就是说这个方法里面是可以保证执行顺序的!!!!而且JVM会保证父类的<clinit>()先执行。除此之外,这个方法在多线程环境下,JVM会保证它的同步语义,有且仅有一个线程执行<clinit>(),并且只会执行一次。

类的加载过程

原文:https://www.cnblogs.com/huangwenhao1024/p/14231959.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!