Что отличает "имя интерфейса" от "имени класса"?

В пункте 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 ответ

Решение

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

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

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

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

Другие вопросы по тегам