JVM 何时装入类?

2022-09-02 13:07:05

假设我有以下类:

class Caller {
  public void createSomething() {
    new Something();
  }
}

将执行此行:

static void main() {
   Class<?> clazz = Caller.class;
}

导致 JVM 加载类,还是类加载延迟到调用方法?SomethingcreateSomething()


答案 1

仅当需要有关类的信息时,才会加载该类。

public class SomethingCaller {
    public static Something something = null; // (1) does not cause class loading
    public static Class<?> somethingClass = Something.class; // (2) causes class loading

    public void doSomething() {
        new Something(); // (3) causes class loading
    }
}

行 (2) 和 (3) 将导致类被加载。Something.class 对象包含的信息(第 (2) 行),这些信息只能来自类定义,因此您需要加载该类。对构造函数 (3) 的调用显然需要类定义。对于类上的任何其他方法也是如此。

但是,行 (1) 不会导致类被加载,因为您实际上不需要任何信息,它只是对对象的引用。

编辑:在你更改的问题中,你问引用某物.class是否加载了类。是的,确实如此。但是,在执行 main() 之前,它不会加载该类。使用以下代码:

public class SomethingTest {
    public static void main(String[] args) {
        new SomethingCaller();
    }
}

public class SomethingCaller {
    public void doSomething() {
        Class<?> somethingClass = Something.class;
    }
}

public class Something {}

此代码不会导致加载某事.class。但是,如果我调用 doSomething(),则类被加载。要对此进行测试,请创建上述类,编译它们并删除 Something.class 文件。上面的代码不会在ClassNotFoundException中崩溃。


答案 2

是的,这将导致在加载包含引用的类时加载该类。不这样做的唯一方法是通过反射引用类。然后,您可以控制何时加载它。File.class