类加载机制

类的生命周期:

1) 加载:查找并加载类的二进制数据

通过一个类的全限定名来获取定义此类的二进制流

  • 从本地系统直接加载
  • 通过网络下载.class文件
  • 从zip,jar等归档文件中加载.class文件
  • 从专有数据库中提取.class文件
  • 将Java源文件动态编译为.class文件(服务器)

将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构

在内存中生成一个代表这个类的class对象,作为这个类的各种数据访问入口

2) 链接:

验证:确保被加载类的正确性;

  • 文件格式验证
  • 元数据验证
  • 字节码验证
  • 符号引用验证

准备:为类的静态变量分配内存,并将其初始化为默认值;

  • (基本类型:int 0 、boolean false、float 0.0、char '0'等等)
  • (抽象数据类型::null)
  • (如果被final修饰,在这个过程常量值会一同被指定)

解析:把类中的符号引用转换为直接引用;

3) 初始化:

  遇到new、getstatic、putstaticinvokestatic这四条指令时,如果类没有进行过初始化,则需要先触发其初始化。

生成这4条指令最常见的Java代码场景是:

1) 使用new关键字实例化对象的时候

2) 读取或设置一个类的静态字段的时候(被final修饰、已在编译器把结果放入常量池的静态字段除外)

3) 调用一个类的静态方法的时候

4) 使用java.lang.reflect包的方法对类进行反射调用的时候(Example:Class.forName("com.lyj.load"))

5) 当初始化一个类的时候,如果发现其父类还没有进行过初始化,则需要先触发其父类的初始化

6) 当虚拟机启动时,用户需指定一个要执行的主类(包含main方法的那个类),虚拟机会先初始化这个类 

不被初始化的情况:

1.通过子类引用父类的静态字段,子类不会被初始化。

2.通过数组来引用类不会被初始化

3.调用类的常量类不会被初始化

 4) 加载

 

原文地址:https://www.cnblogs.com/smokerBig/p/10335143.html