Как jvm проверяет, загружен класс или нет, когда класс используется впервые - PullRequest
0 голосов
/ 21 марта 2020

Вопрос

когда 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, но с # 1, будет ли класс MyObject загружен на # 2, и как jvm судит?

1 Ответ

1 голос
/ 21 марта 2020

Каждый ClassLoader хранит список классов, которые он загрузил до сих пор.

Если два разных ClassLoader загружают класс с одинаковым именем, они рассматриваются средой выполнения как два отдельных несвязанных класса , Это полезно, потому что это позволяет различным версиям одного и того же класса сосуществовать во время выполнения. Например, мы можем развернуть несколько веб-приложений, разработанных разными командами, в одну и ту же JVM, каждая со своими собственными библиотеками, что освобождает разработчиков различных приложений от согласования версий используемых ими библиотек.

В вашем случае , если мы делаем new MyObject() в классе Main, загрузчик класса, который загрузил класс Main, должен загрузить класс MyObject. Это система ClassLoader, которая ничего не знает о вашем myLoader. Поэтому загрузчик системного класса снова загрузит класс MyObject.

В этом можно убедиться, добавив инициализатор stati c в MyObject:

class MyObject {
    static {
        System.out.println("class MyObject has been loaded");
    }
}
...