java类加载机制

本文详细介绍了Java类的加载过程,包括加载、验证、准备、解析、初始化等步骤,以及对象初始化顺序和类加载器的工作原理。深入探讨了类加载器的双亲委派模型,帮助理解类的生命周期。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

##1、类加载过程
     类的生命周期如下图所示:
这里写图片描述
可以看到类的生命周期包含了**加载、验证、准备、解析、初始化、使用、卸载七个步骤,**其中验证、准备和解析可以叫做一步连接。其中类的加载过程是前面的步,加载、验证、准备、解析和初始化。接下来详细介绍每个步骤要干的事情。首先是加载,加载要完成三件事情,首先将通过一个类的全限定名获取到类的class文件,然后将class文件中的字节流按照虚拟机规定的运行时的数据结构存储在方法区中,最后在内存中生成一个代表这个类的class对象,作为访问这些数据的入口。获取class文件的途径很多,可以从网络获取,压缩包获取,运行时计算获取(动态代理)等等。**然后是验证,验证阶段主要是对class文件中的字节流所包含的数据进行检查,看是否符合当前虚拟机的标准,是否会危害当前虚拟机的安全。具体包含了文件格式验证,元数据验证,字节码验证,符号引用验证,**首先文件格式验证主要是雅正class文件格式是否符合虚拟机的要求,能不能被当前虚拟机处理。包含了魔数验证,版本号验证,是否有不支持的常量等等。**这个阶段验证完成后才会将class文件中的字节流加载到内存中。**然后是元数据验证,元数据即是对类的描述数据,主要验证对类的描述数据代表的语义是否符合java的语法,例如,这个类继承的类是否正确,是否实现了接口中所有的方法,类中重载的规则对不对等等。接着是字节码验证,字节码验证主要来验证程序的逻辑是否符合java语法,比如是否有不符合要求的类型转换等。最后是符号引用验证,符号引用是用来保证解析过程能够正常执行,所以符号引用也发生在解析的时候,主要是验证符号引用是否能找到被引用对象等。如果这个class文件已经被反复验证过为了提高效率可以通过设置参数来取消对某个类的验证。
**验证过后是准备,**准备就是为类变量(static)分配内存并且分配初始值,这里的初始值是0值或者false等。但如果是被final修饰的变量会直接赋对应的值。**然后是解析,**解析就是将符号引用转化为直接引用,这里符号引用就是对引用对象的一个由符号组成的描述符,通过符号引用可以定位到目标。在编译阶段编译器并不知道引用对象的地址所以只能用符号引用来定位目标。直接引用就是目标的地址或者能找到对象的句柄的地址。**最后是初始化,**初始化是对静态变量赋初值并且对其他资源进行初始化,例如静态语句块。java中对类加载的时机没有强制的要求,但是对类的初始化时机有具体的要求。有且只有一下5中情况会对类进行初始化,
1、new一个对象,调用类的静态字段或者静态方法。
2、对类进行反射调用的时候
3、初始化类的时候其父类没有初始化,会对父类进行初始化。
4、虚拟机启动后,main方法所处的类会被初始化
5、如果一个java.lang.invoke.MethodHandle实例最后的解析结果REF_getStatic、 REF_putStatic、 REF_invokeStatic的方法句柄,并且这个方法句柄所对应的类没有进行过初始化,则需要先触发其初始化。
类的初始化的前提是类已经被加载了进来。类的加载过程这几个阶段的顺序通常是交叉进行的,例如验证的第一个阶段完成后类才会真正的被加载到内存中。

##2、对象的初始化顺序
     首先对象初始化会有几个东西,构造函数,构造代码块,静态代码块,静态变量,对于构造函数,构造函数只会初始化一次,用来初始化对象,构造方法只会调用一次,对象的方法可以重复调用,对于构造方法块,同构造方法一样只会在new的时候执行一次,也是用来初始化对象的,对于静态代码块,是给类进行初始化的,只会在类初始化的时候执行一次,对于静态变量,也只会在类初始化的时候初始化一次。**对于一个类,**这几个的顺序如下,静态变量和代码块优先于构造代码块优先于构造函数。对于有继承的情况,这几个的顺序如下,父类静态变量、代码块优先于自雷静态变量、代码块优先于父类变量、构造代码块、构造方法优先于子类变量、构造代码块、构造方法。

##3、类加载器
     类加载器用于实现类的加载,java中分为了三种类加载器,启动类加载器,拓展类加载器,应用程序类加载器,其中启动类加载器是由C++编写,用于加载JAVA_HOME>\lib目录下的类,也就是我们用到的基本的像String什么的都是这个加载器加载的。然后是拓展类加载器是用于加载<JAVA_HOME>\lib\ext中的类,这个目录下的类不常用到,最后应用程序类加载器是加载用户自己实现的类。接下来介绍下类加载器的双亲委派模型,图示:
这里写图片描述
双亲委派模型体现了类加载器之间的层次模型,除了启动类加载器外,每个加载器都有自己的父加载器,工作过程如下:如果类加载器收到了类加载的请求,那么会将这个请求一层一层的传递到父加载器中,当父加载器反馈自己不能加载的时候才会有这个加载器加载,这样的好处是,避免一个类被多个加载器重复加载,并且由于不同加载器加载的类是不一样的,导致程序混乱。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值