JVM什么时候加载类?

发布于 2024-12-06 18:15:51 字数 312 浏览 0 评论 0原文

假设我有以下类:

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

执行此行:会

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

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

Assume I have the following class:

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

Would executing this line:

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

cause the JVM to load the class Something or is the class loading deferred until the method createSomething() is called?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

好多鱼好多余 2024-12-13 18:15:52

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

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) 行不会导致类被加载,因为您实际上不需要任何信息,它只是对对象的引用。

编辑:在您更改的问题中,您询问是否引用 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.class 被加载。但是,如果我调用 doSomething(),则会加载该类。要测试这一点,请创建上述类,编译它们并删除 Something.class 文件。上面的代码不会因 ClassNotFoundException 而崩溃。

A class is loaded only when you require information about that class.

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
    }
}

The lines (2) & (3) would cause the class to be loaded. The Something.class object contains information (line (2)) which could only come from the class definition, so you need to load the class. The call to the constructor (3) obviously requires the class definition. Similarly for any other method on the class.

However, line (1) doesn't cause the class to be loaded, because you don't actually need any information, it's just a reference to an object.

EDIT: In your changed question, you ask whether referring to Something.class loads the class. Yes it does. It does not load the class until main() is executed though. Using the following code:

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

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

public class Something {}

This code does not cause the Something.class to be loaded. However, if I call doSomething(), the class is loaded. To test this, create the above classes, compile them and delete the Something.class file. The above code does not crash with a ClassNotFoundException.

夏至、离别 2024-12-13 18:15:52

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

Yes, that will cause the class to load when the class containing the File.class reference is loaded. The only way to not do this is to reference a class by reflection. Then you can control when it's loaded.

梦与时光遇 2024-12-13 18:15:52

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

您需要查看 ClassLoader 类中的 loadClassfindClass 以及可能的 defineClass 方法,覆盖加载并查找并在实现中使用defineClass。关于编写自定义类加载器的谷歌搜索将显示许多示例代码来执行此操作,但基本上您将在映射中缓存类结果(类名到类),然后提供一些回调机制以从缓存中删除加载的类当不需要它们时。

祝你好运。

If you have performance requirements this strict, you should consider writing a custom ClassLoader object. This would let you can dump classes from memory when they aren't needed any more.

You'll want to check out the loadClass, findClass and probably the defineClass methods in the ClassLoader class, overriding load and find and using defineClass in the implementation. A google search on writing custom class loaders will reveal lots of sample code to do this, but basically you are going to cache the class results in a Map (class name to Class), then provide some callback mechanism to remove loaded classes from your cache when they aren't needed.

good luck.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文