Что отличает "имя интерфейса" от "имени класса"?
В пункте 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
) напрямую.