Экземпляр класса, полученный через загрузчик нескольких классов - PullRequest
6 голосов
/ 21 марта 2011

Я читал эту статью, и там говорится, что:

Если у нас есть два экземпляра класса Student, загруженных этими CustomClassLoaders, скажем student1 и student2, тогда student1 и student2не совместимы по типу.Другими словами,

Студент ученик3 = (Студент) ученик2;

вызовет исключение ClassCastException, потому что JVM видит эти два как отдельные, различные типы классов, так как они определяются различными экземплярами ClassLoader.

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

Но пример, который он использовал, сбивает меня с толку, то есть

Student student3 = (Student) student2;

Разве это не так, когда мы объявляем ссылочную переменнуюкак Student student , все, что ищет компилятор, - это то, что этот Studnet присутствует в его правильном расположении в соответствии с его структурой пакета. Теперь, когда во время выполнения мыприсвоить эту ссылочную переменную реальному загруженному классу, действительно ли имеет значение, какой загрузчик классов мы используем для загрузки указанного класса? Я сомневаюсь, потому что, насколько я понимаю, загрузчик классов вступает в игру только тогда, когда мы делаем 'new' или мы вызываемстатическое поле на нем, а не когда мы просто объявляем его тип.

Пожалуйста, разъясните мне это и помогите мне исправить мое понимание в этом отношении.

Спасибо, Мавия

Ответы [ 2 ]

3 голосов
/ 21 марта 2011

Это в основном правильно, но когда назначение происходит, JVM должна убедиться, что это правильно. Поэтому он проверяет: могу ли я назначить правую сторону (RHS) левой стороне (LHS).

В правилах говорится, что это разрешено, когда вы можете уменьшить тип времени выполнения RHS до типа LHS.

Итак, во время компиляции приведенный выше код выглядит нормально. Но во время выполнения вызов isAssignableFrom() возвращает false, потому что эти два типа различны.

Метод equals() в Class возвращает true, если квалифицированные имена равны и , когда загрузчик классов одинаков. Вот почему в этом случае вы получаете ClassCastException.

Используемые методы реализованы как собственный код, поэтому вы не можете видеть, что происходит. Но методы isInstance() и isAssignableFrom() возвращают true только тогда, когда загрузчик классов для обоих классов одинаков.

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

Да, во время выполнения действительно имеет значение, какой загрузчик классов загрузил класс. И загрузчик классов проверяется каждый раз, когда класс должен быть загружен. Это не только когда встречается new или статическое поле. Это происходит каждый раз, когда имя класса появляется в Java-коде, или, если быть более точным, когда на имя класса ссылаются в байтовом коде и выполняется байтовый код.

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