Почему в стеке появляется sun.misc.Launcher$AppClassLoader.loadClass
Я инструментировал JDK и приложение. Точки входа и выхода записываются для построения графа вызовов.
График вызовов выглядит как
sun.misc.Launcher $ AppClassLoader.loadClass-> com.example.Main.main
-> sun.misc.Launcher $ AppClassLoader.loadClass-> com.example.Foo.foo
Исходный код
public class Main{
public static void main(String[] args){
Foo.foo()
}
}
public class Foo{
public static void foo(){};
}
Это должно быть, как работает classloader, но я не вижу ничего, что показывает в байт-коде, который указывает на сайт вызова "sun.misc.Launcher$AppClassLoader.loadClass". Итак, как работает classloader внутри?
2 ответа
Занятия загружаются лениво.
Это можно увидеть написав код для печати на консоли в статических инициализаторах.
В первый раз, когда ссылка на класс используется любым кодом, загруженным определенным загрузчиком классов, JVM запрашивает Class
от загрузчика в текущей теме. Если загрузчик родительского класса не загрузил класс полностью определенного имени, то текущий загрузчик класса определит его (или сгенерирует исключение).
В первые дни апплеты устанавливали сетевое соединение для каждого файла класса.
Взгляните на:https://www.infoworld.com/article/3700054/all-about-java-class-loaders.html В JVM есть как минимум 3 разных загрузчика классов — больше, если вы хотите использовать свой собственный. Короче говоря, загрузчик классов, который загрузил класс, которому нужен новый класс, вызывает его загрузчик классов, который, в свою очередь, вызывает свой загрузчик классов и т. д., если загрузчик классов верхнего уровня не может его найти, он возвращается обратно в иерархию. Вышеупомянутая ссылка дает красивую картинку.