Как класс загружается двумя загрузчиками классов (предположим, что оба являются URLClassLoader) на одном уровне в иерархии загрузчиков классов Java. - PullRequest
0 голосов
/ 10 мая 2019

Недавно я начал изучать, как именно работает загрузчик классов в Java.Ниже приведены три пункта, которые я наблюдал:

Точка-1: У каждого загрузчика классов есть родительский загрузчик классов.Когда загрузчику классов предлагается загрузить класс или ресурс, он обращается к своему родительскому загрузчику классов, прежде чем пытаться загрузить сам элемент.Родитель, в свою очередь, консультируется со своим родителем и так далее.Таким образом, только после того, как все загрузчики класса-предка не могут найти элемент, текущий загрузчик класса включается.

Point-2: один и тот же класс, загруженный двумя загрузчиками, рассматривается как два разных классаюридическое лицо.мы даже не можем привести один объект класса (loader 1) к другому классу (загруженному loader2).он выдаст ClassCastException.

Точка-3: Загрузчик дочернего класса может проверить кэш загрузчика родительского класса, но родитель не может видеть классы, загруженные дочерним элементом.

Исходя из вышеизложенного, у меня есть два вопроса:

Ситуация: Я создал объект URLClassloader url1 и другой объект URLClassloader url2 в том же приложении.как мы знаем, по умолчанию оба загрузчика классов будут иметь один и тот же родительский загрузчик классов.просто предположим, что загрузчик родительского класса - это SystemClassLoader.

Вопрос 1: url1 classloader загрузил класс A.class из местоположения x / abc.jar.снова url2 хочет загрузить тот же класс из того же места.будет ли url2 загружать свежее или будет использовать тот же, что загружен url1?Я пытался проверить, только когда исполнялся статический блок, поэтому загруженный класс загружался только один раз.что, согласно моему пониманию, не удовлетворяет пункту 1 и пункту 3.

Вопрос 2: Может ли загрузчик классов url2 проверить кэш загрузчика классов url1.относится к точке-3.

1 Ответ

0 голосов
/ 10 мая 2019

Загрузчики классов полностью независимы, поэтому вы получаете два разных класса.

Так как вы не опубликовали MCVE (пример Минимальный, Полный и Проверяемый), вот один из них, использующий произвольно выбранный файл .jar.

public static void main(String[] args) throws Exception {
    String jarFile = "/path/to/commons-lang3-3.8.1.jar";

    URLClassLoader url1 = new URLClassLoader(new URL[] { new File(jarFile).toURI().toURL() });
    URLClassLoader url2 = new URLClassLoader(new URL[] { new File(jarFile).toURI().toURL() });

    Class<?> fractionClass1 = url1.loadClass("org.apache.commons.lang3.math.Fraction");
    Class<?> fractionClass2 = url2.loadClass("org.apache.commons.lang3.math.Fraction");

    Object oneHalf1 = fractionClass1.getField("ONE_HALF").get(null);
    Object oneHalf2 = fractionClass2.getField("ONE_HALF").get(null);

    System.out.println("url1 = " + url1);
    System.out.println("url2 = " + url2);
    System.out.println(" Same? " + (url1 == url2));
    System.out.println("fractionClass1 = " + fractionClass1);
    System.out.println("fractionClass2 = " + fractionClass2);
    System.out.println(" Same? " + (fractionClass1 == fractionClass2));
    System.out.println("oneHalf1 = " + oneHalf1);
    System.out.println("oneHalf2 = " + oneHalf2);
    System.out.println(" Same? " + (oneHalf1 == oneHalf2));
}

выход

url1 = java.net.URLClassLoader@1e81f4dc
url2 = java.net.URLClassLoader@4d591d15
 Same? false
fractionClass1 = class org.apache.commons.lang3.math.Fraction
fractionClass2 = class org.apache.commons.lang3.math.Fraction
 Same? false
oneHalf1 = 1/2
oneHalf2 = 1/2
 Same? false
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...