CrazyDailyQuestion icon indicating copy to clipboard operation
CrazyDailyQuestion copied to clipboard

2019-10-23: 请谈谈Java的类加载过程?

Open yuejunfei opened this issue 5 years ago • 2 comments

yuejunfei avatar Oct 23 '19 01:10 yuejunfei

Java类加载过程完整生命周期分为:

  • load

    • 加载 Class

      • 通过 Class 全限定名获取二进制字节流
      • Class 文件加载到方法区
      • 在内存中生成java.lang.Class表示这个Class
    • 获取 Class

      • zip中获取,如: 从 jar,war,ear等格式的文件中读取Class文件内容。
      • 从网络获取,如: Applet
      • 动态生成,如: 动态代理,ASM框架等都是这种形式
      • 由其他文件生成,典型的是从ASP中生成相应的Class
  • verify: 验证一个class文件是否合法,主要包括以下三个阶段

    • 文件格式验证

      • 确保文件格式符合Class文件格式规范,如: 验证魔数,版本号
    • 元数据验证

      • 确保Class的语义描述符合JavaClass规范,如:该Class是否有父类。
    • 字节码验证

      • 通过分析数据流和控制流,确保语义符合逻辑,如:验证类型转换是否合法。
    • 符号引用验证

      • 验证引用的类,成员变量,方法是否被访问,当前类是否存在相应的方法,成员等
  • prepare

public static int a = 123;

在准备阶段后,a 在内存中的值仍然为0,赋值 123 这个操作会在中初始化阶段执行,因此在初始化阶段产生对应的Class对象才是123

  • resolve

解析阶段,虚拟机会将常量池中的符号替换为直接引用,解析针对的是类,接口,方法,成员变量等符号引用。在转变成直接引用后,会触发校验阶段的符号引用验证,验证转换之后的直接引用是否能找到对应的类,方法,成员变量等,这里的可见类加载在各个阶段实际过程中可能是交错执行。

  • init
public class Singleton {
     public static final INSTANCE = new Singleton();
     private Singleton() {
     }
 }
  • use
  • unlod

MicroKibaco avatar Oct 24 '19 01:10 MicroKibaco

楼上说的很好,那我说下 一个对象实例化过程吧 例如:zi p = new zi();

  1. JVM会读取指定的路径下的zi.class文件,并加载进内存, 并会先加载zi的父类(如果有直接的父类的情况下).
  2. 在堆内存中的开辟空间,分配地址。
  3. 并在对象空间中,对对象中的属性进行默认初始化。
  4. 调用对应的构造函数进行初始化。
  5. 在构造函数中,第一行会先到调用父类中构造函数进行初始化。
  6. 父类初始化完毕后,在对子类的属性进行显示初始化。
  7. 在进行子类构造函数的特定初始化。
  8. 初始化完毕后,将地址值赋值给引用变量.

peiniwan avatar Oct 24 '19 06:10 peiniwan