JVM何时加载类?



假设我有以下类:

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

将执行这一行:

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

导致JVM加载类Something还是类加载延迟到方法createSomething()被调用?

只在需要该类信息时才加载该类。

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)会导致类被加载。class对象包含只能来自类定义的信息(第(2)行),因此需要加载类。对构造函数(3)的调用显然需要类定义。对于类上的任何其他方法也是如此。

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

编辑:在你改变的问题中,你问是否引用Something.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 {}

这段代码不会导致加载something .类。然而,如果我调用doSomething(),类就会被加载。为了测试这一点,创建上面的类,编译它们并删除Something.class文件。上面的代码不会因为ClassNotFoundException而崩溃。

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

如果您有如此严格的性能要求,您应该考虑编写一个自定义ClassLoader对象。这将允许您在不再需要时从内存中转储类。

您将需要检查loadClass, findClassdefineClass方法在ClassLoader类中,重载加载和查找并在实现中使用defineClass。在谷歌上搜索一下编写自定义类加载器,你会发现很多这样做的示例代码,但基本上你要把类的结果缓存在一个Map(类名到类)中,然后提供一些回调机制,在不需要的时候从缓存中删除加载的类。

好运。

相关内容

  • 没有找到相关文章