Класс А не равен Классу А - PullRequest
5 голосов
/ 13 сентября 2011

У нас есть кеш (Map) с объектами класса TestClass. Другой загрузчик классов снова инициализирует / загружает TestClass во время выполнения, поэтому приведенный ниже код выдаст ClassCastException:

TestClass obj1 = (TestClass)map.get("key"); // throws a ClassCastException

ClassCastException при приведении к тому же классу

Хорошо, я понимаю этот вопрос до этого момента.

Итак, я пытался найти справочную информацию, почему TestClass.class не равно TestClass.class. Я предполагаю, что другой загрузчик классов установил другой идентификатор для ReferenceType? Кто-нибудь может объяснить мне фон?

Лучшая страница, которую я нашел: http://www.objectsource.com/j2eechapters/Ch21-ClassLoaders_and_J2EE.htm

Ответы [ 4 ]

8 голосов
/ 13 сентября 2011

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

Я думаю, что разница просто в том, что в игре есть два разных объекта токенов класса. Это должно быть так, поскольку классы, загружаемые разными загрузчиками, на самом деле могут быть разными версиями одного и того же класса. Известно, что маркер класса для каждого класса уникален (то есть в одной области загрузчика классов). Если бы JVM начала сравнивать токены классов по их различным атрибутам, а не по физическому равенству (==), то это открыло бы банку с червями.

1 голос
/ 13 сентября 2011

Тайны нет.Равенство типов во время выполнения определяется в Спецификации языка Java следующим образом:

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

JLS 4.3.4 - При ссылкетипы одинаковы .(2-й абзац)

1 голос
/ 13 сентября 2011

Кто-нибудь может объяснить мне фон?

Как уже объяснил Петер Тёрёк, они считаются разными при загрузке из разных загрузчиков классов. Предпосылкой является то, что сервер приложений должен иметь возможность поддерживать разные версии приложения, например разные версии одних и тех же библиотек включены в ваши ear-файлы.

1 голос
/ 13 сентября 2011

То, что вы испытали, является причиной существования пользовательских загрузчиков классов. Они позволяют загружать разные классы с одинаковыми именами в одну JVM. Идентификация класса в JVM дается кортежем, состоящим из имени класса и загрузчика класса. В языке Java класс идентифицируется только по полному имени.

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