Java есть способ загрузить класс, который уже был загружен System ClassLoader другим? - PullRequest
3 голосов
/ 10 февраля 2012

(ужасное название, я знаю)

Лучший способ объяснить это - мне нужно загрузить некоторые классы, которые будут загружены во время выполнения, из URLClassLoader, поскольку эти классы имеют ссылки на экземпляры классов, которые уже загружены System ClassLoader, и не могут перезагружаться из-за некоторых других проблем.

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

Ответы [ 3 ]

3 голосов
/ 10 февраля 2012

Нет. Каждый загрузчик классов имеет загрузчик классов начальной загрузки в качестве предка, и попытка загрузить класс, который уже определен в загрузчике классов, просто приведет к использованию версии предка. Это сделано для предотвращения переопределения java.lang.Object и других встроенных функций.

Из Javadoc для ClassLoader:

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

Вы можете определить пользовательский загрузчик классов, который предоставляет defineClass, без вызова findClass и избежать делегирования, которое происходит в findClass, но я бы не стал полагать, что defineClass(className, bytes) работает так, как задумано для всех JVM, когда существует parent.findClass(className).

1 голос
/ 10 февраля 2012

Да.Но вы должны быть немного осторожнее, потому что загрузчик родительского класса по умолчанию - это загрузчик системного класса, а не загрузчик.Я предлагаю использовать java.net.URLClassLoader.newInstance(myURLs, null).Если вы хотите быть flash, получите загрузчик родительского класса из системного загрузчика классов, и он будет включать классы расширения.

(Обратите внимание, терминология немного искажена, потому что она датируется до Java2, когда classpath включал то, чтотеперь bootclasspath (боль для установщиков). Поэтому системные классы не загружаются загрузчиком системных классов.)

1 голос
/ 10 февраля 2012

Да, вы можете определить другой загрузчик классов и загрузить класс.

Согласно спецификации

"Во время выполнения класс или интерфейс определяется не только своим именем, но парой: его полностью определенным именем и определяющим загрузчиком классов.Каждый такой класс или интерфейс принадлежит одному пакету времени выполнения. Пакет времени выполнения класса или интерфейса определяется по имени пакета и определяющему загрузчику класса класса или интерфейса."

...