ClassLoader путаница - PullRequest
       10

ClassLoader путаница

10 голосов
/ 03 апреля 2009

Я видел несколько мест, где «Class.getClassLoader () возвращает ClassLoader, использованный для загрузки этого конкретного класса», и поэтому я озадачен результатами следующего примера:


package test;

import java.lang.*;

public class ClassLoaders { 
    public static void main(String[] args) throws java.lang.ClassNotFoundException{
      MyClassLoader mcl = new MyClassLoader();
      Class clazz = mcl.loadClass("test.FooBar");
      System.out.println(clazz.getClassLoader() == mcl); // prints false
      System.out.println(clazz.getClassLoader()); // prints e.g. sun.misc.Launcher$AppClassLoader@553f5d07
    }
}

class FooBar { }

class MyClassLoader extends ClassLoader { }

Не должен ли оператор clazz.getClassLoader () == mcl вернуть true? Может кто-нибудь объяснить, что мне здесь не хватает?

Спасибо.

Ответы [ 3 ]

17 голосов
/ 03 апреля 2009

Каждый раз, когда вы создаете свой собственный загрузчик классов, он будет присоединен к древовидной иерархии загрузчиков классов. Для загрузки класса загрузчик классов сначала делегирует загрузку его родителю. Только после того, как все родители не найдут класс, загрузчик, которого сначала попросят загрузить класс, попытается загрузить его.

В вашем конкретном случае загрузка делегируется родительскому загрузчику классов. Хотя вы просите MyClassLoader загрузить его, загрузкой занимается родитель. В данном случае это AppClassLoader.

6 голосов
/ 03 апреля 2009

Ссылаясь на документ API ClassLoader :

Каждый экземпляр ClassLoader имеет связанный родительский загрузчик классов. когда попросили найти класс или ресурс, экземпляр ClassLoader будет делегировать поиск класса или ресурса до его родительского загрузчика класса до пытаясь найти класс или сам ресурс.

0 голосов
/ 03 апреля 2009

Если самоопределенный загрузчик классов делегирует вызов загрузчику классов ВМ, который загружает класс. clazz.getClassLoader () вернет этот загрузчик классов.

Чтобы разобраться в деталях: Javadoc класса ClassLoader предоставляет следующее объяснение порядка выполненных шагов:

Загружает класс с указанным двоичное имя По умолчанию реализация этого метода поиска для занятий в следующем порядке:

  1. Вызвать findLoadedClass (String), чтобы проверить, был ли класс уже загружен.
  2. Вызвать метод loadClass в загрузчике родительского класса. Если родитель нулевой загрузчик классов, встроенный в вместо этого используется виртуальная машина.
  3. Вызовите метод findClass (String), чтобы найти класс.

Поскольку вы унаследовали без изменения методы, это поведение не изменится. Шаг 2 будет тем, где класс будет загружен. Когда вы вызываете конструктор ClassLoader без параметров (автоматически, так как вы не определили конструктор в MyClassLoader), вы автоматически используете встроенный ClassLoader.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...