Java教程

Java的类加载过程

本文主要是介绍Java的类加载过程,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

类加载的过程如下图所示:
在这里插入图片描述

一、加载阶段

注意:这里的“加载”阶段是整个“类加载”过程的一个阶段,两个词的含义是不一样的。
这个阶段主要做3件事:
1. 通过类的全限定名获取二进制字节流;
2. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构;
3. 在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口。

二、链接阶段

验证

这一步的目的是为了保证加载进来的字节流符合《Java虚拟机规范》的要求,不会造成安全错误。

  • 包括对于文件格式的验证,比如常量中是否有不被支持的常量?文件中是否有不规范的或者附加的其他信息?

  • 对于元数据的验证,比如该类是否继承了被final修饰的类?类中的字段,方法是否与父类冲突?是否出现了不合理的重载?

  • 对于字节码的验证,保证程序语义的合理性,比如要保证类型转换的合理性。

  • 对于符号引用的验证,比如校验符号引用中通过全限定名是否能够找到对应的类?校验符号引用中的访问性(private,public等)是否可被当前类访问?

准备

准备阶段主要是为静态变量分配内存,并为这些变量赋初始值。

这些便变量分配到哪儿了呢?没错,是方法区。

这里需要注意的是:此阶段所赋的初始值并不一定是代码中的的初始化值。
8种基本类型的初值,默认为0;引用类型的初值则为null;常量的初值即为代码中设置的值。
举例1:
public static int love = 520
这种情况下,准备阶段love会被赋值为0;
public static final int love = 520
加了final关键字后,love在准备阶段会被赋值为520。

解析

将常量池内的符号引用替换为直接引用的过程。

  • 符号引用:即一个字符串,但是这个字符串给出了一些能够唯一性识别一个方法,一个变量,一个类的相关信息。
  • 直接引用:可理解为一个内存地址,或者一个偏移量。比如类方法,类变量的直接引用是指向方法区的指针;而实例方法,实例变量的直接引用则是从实例的头指针开始算起到这个实例变量位置的偏移量
    举个例子来说,现在调用方法hello(),这个方法的地址是1234567,那么hello就是符号引用,1234567就是直接引用。

在解析阶段,虚拟机会把所有的类名,方法名,字段名这些符号引用替换为具体的内存地址或偏移量,也就是直接引用。

初始化

初始化阶段主要是对类变量初始化,是执行类构造器的过程。

换句话说,只对static修饰的变量或语句进行初始化。

如果初始化一个类的时候,其父类尚未初始化,则优先初始化其父类。

如果同时包含多个静态变量和静态代码块,则按照自上而下的顺序依次执行。

这篇关于Java的类加载过程的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!