0

问题

当 jvm 运行以下代码时

MyObject o=new MyObject() //first access MyObject

我们知道 jvm 将启动 MyObject 的加载类,但我想知道 jvm 是如何知道 MyObject 未加载的。

动机

我想知道,因为如果 jvm 运行这些代码

public class Main{
  public static void main(){
     ClassLoader myLoader = new ClassLoader(null) {
            @Override
            protected Class<?> findClass(String name) throws ClassNotFoundException {
                // omitted here
            }
        }
     myLoader.loadClass("MyObject"); //#1
     MyObject o=new MyObject() //#2
  }
}

我们知道没有#1,MyObject 会被Main 类的classloader 加载,但是有了#1,MyObject 的类会在#2 加载,jvm 是如何判断的呢?

4

1 回答 1

1

每个都ClassLoader保留一个它到目前为止已加载的类的列表。

如果两个不同ClassLoader的类加载同名的类,则运行时会将它们视为两个独立的不相关类。这很有用,因为它允许同一类的不同版本在运行时共存。例如,我们可以将不同团队开发的多个 Web 应用程序部署到同一个 JVM 中,每个应用程序都有自己的库,从而使各种应用程序的开发人员无需协调他们使用的库的版本。

在您的情况下,如果我们new MyObject()在 class中执行,则要求Main加载 class 的类加载器加载class 。这就是系统,它对你的. 因此,系统类加载器会再次加载类。MainMyObjectClassLoadermyLoaderMyObject

您可以通过向 MyObject 添加静态初始化程序来验证这一点:

class MyObject {
    static {
        System.out.println("class MyObject has been loaded");
    }
}
于 2020-03-21T19:56:52.083 回答