Java类加载:静态语句和类加载哪个先发生?

Java类加载机制:类加载优先于静态语句初始化

关于Java类加载的顺序,一个常见的问题是:在执行以下代码时,是先加载类A,还是先执行静态语句f()

class A {
 

public static void f() {} } A a = new A();

答案是:先加载类,再初始化静态语句

类加载过程详解

Java的类加载过程包含三个主要阶段:加载、链接和初始化。 其中,“加载”阶段排在最前。静态语句的初始化则发生在“初始化”阶段,因此在类加载之后。

详细步骤:

  1. 加载: JVM首先加载类A的字节码文件。
  2. 链接: 链接阶段包括验证、准备和解析三个步骤,确保类的正确性。
  3. 初始化: 在这个阶段,JVM才开始执行静态语句块和静态变量的赋值。A.f()方法的代码在此时被初始化,但并不被执行,除非显式调用。
  4. 实例化: A a = new A(); 这行代码创建A类的实例。此时,除了静态成员外,还会初始化非静态变量、非静态代码块以及构造函数。

实例化对象的初始化顺序

当实例化对象a时,初始化顺序如下:

  1. 父类静态变量和静态代码块(如果有父类)
  2. 本类静态变量和静态代码块
  3. 父类非静态变量和非静态代码块(如果有父类)
  4. 本类非静态变量和非静态代码块
  5. 父类构造函数(如果有父类)
  6. 本类构造函数

更深入的类加载机制细节,可以参考深入理解Java类加载流程 这篇文章。