Что отличает «имя интерфейса» от «имени класса»? - PullRequest
0 голосов
/ 26 января 2019

В параграфе 4.4.2 спецификации Java 8 (аналогично в некоторых других местах) упоминается

class_index

Значение элемента class_index должно быть допустимым индексом в таблице constant_pool. Запись constant_pool в этом индексе должна быть структурой CONSTANT_Class_info (§4.4.1), представляющей класс или тип интерфейса, который имеет поле или метод в качестве члена.

Элемент class_index структуры CONSTANT_Methodref_info должен быть типом класса, а не типом интерфейса.

Я огляделся, но, насколько я могу судить, невозможно только по одному байт-коду отличить типы интерфейсов от типов классов, т. Е. Фактически проверить это требование перед разрешением именованного класса / интерфейса во время выполнения против загрузчика классов. .

Правильно ли я в этом предположении или я пропустил способ проверить это требование на предмет наличия единственного CONSTANT_Class_info в отдельном файле класса?

1 Ответ

0 голосов
/ 28 января 2019

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

Кроме CONSTANT_Methodref_info ожидания, что объявленный тип не является интерфейсом, и CONSTANT_InterfaceMethodref_info ожидания, что он является интерфейсом, наличие ссылки на тип в Поле super_class подразумевает неинтерфейсный тип, тогда как любой тип, присутствующий в массиве interfaces , подразумевает интерфейс.

В случае вложенных типов вы можете проверить атрибут InnerClasses., в котором перечислены все вложенные типы с их флагами доступа, включая ACC_INTERFACE.

Кроме того, каждый тип, используемый в качестве аннотации, технически является интерфейсом, хотя атрибуты аннотации не используют элементы CONSTANT_Class_info пулано лучше обращайтесь к именам типов и строкам подписи (CONSTANT_Utf8_info) напрямую.

...