Неверный результат, возвращаемый isAbstract() класса Modifier
Насколько я понимаю, следующий код должен печатать False
, однако, когда я запускал этот код, он печатает True
.
Из документов Java:
Возвращает true, если аргумент integer включает абстрактный модификатор, в противном случае - false.
public class Test{
public static void main(String[] args) {
System.out.println(Modifier.isAbstract(byte[].class.getModifiers()));
}
}
Может ли кто-нибудь помочь мне понять это поведение?
Ответы
Ответ 1
Javadoc из int java.lang.Class.getModifiers() указывает, что должно быть возвращено для некоторых модификаторов для типов массивов (например, final
модификатор должен быть true
а модификатор interface
должен быть false
). С другой стороны, он не указывает, какие abstract
или static
модификаторы должны быть для типов массивов, а это означает, что решение о возврате true
или false
не документировано в JDK. Поэтому любая реализация может выбрать либо true
либо false
.
int java.lang.Class.getModifiers()
Возвращает модификаторы языка Java для этого класса или интерфейса, закодированные в целое число. Модификаторы состоят из констант виртуальной машины Java для общедоступных, защищенных, частных, конечных, статических, абстрактных и интерфейсов; они должны быть декодированы с использованием методов класса Modifier.
Если базовый класс является классом массива, то его общедоступные, частные и защищенные модификаторы такие же, как у его типа компонента. Если этот класс представляет примитивный тип или void, его общедоступный модификатор всегда прав, а его защищенные и частные модификаторы всегда являются ложными. Если этот объект представляет класс массива, примитивный тип или void, то его окончательный модификатор всегда верен, а его модификатор интерфейса всегда является ложным. Значения других модификаторов не определяются этой спецификацией.
Кодировки модификаторов определены в Спецификации виртуальной машины Java, таблица 4.1.
Ответ 2
Указание на подобное поведение можно найти в JLS, 10.8. Объекты класса для массивов:
Каждый массив имеет связанный объект класса, совместно используемый всеми другими массивами с одним и тем же типом компонента.
Хотя тип массива не является классом, объект класса каждого массива действует так: [snipped]
Согласно этому рассуждению массив не является "реальным" классом, поэтому он определенно не является конкретным классом. Такая же логика применима к int.class
который считается абстрактным.
Ответ 3
В определении абстрактного говорится:
Абстрактный класс - это неполный класс, который считается неполным.
Если бы существовал чистый массив, подобный []
то он был бы действительно неполным, поскольку не предоставляется тип компонента.
Это нарушит спецификацию 15.10.1. Выражения создания массива:
Это ошибка времени компиляции, если класс ClassOrInterfaceType не обозначает повторяемый тип.
Он не просто обозначает тип повторного типа, но не тип вообще. Таким образом, было бы невозможно создать экземпляры []
- точно так же, как для абстрактных классов.
Поскольку нет чистого массива []
это всего лишь предположение. Кроме того, модификаторы были возвращены для byte[]
. Это остается спецификацией, показанной Эраном.
Ответ 4
Моя эксплантация будет состоять в том, что массивы считаются abstract
поскольку они создаются самим JVM.
Просто нет конкретного класса для любого типа массива.
Массив имеет контракт, определенный JLS:
- Доступность индексов
- Реализация для
Cloneable
и Serializable
Но никто, кроме самого языка, не может это выполнить, потому что мы не можем действительно заявить о себе.
Ответ 5
Из моего понимания спецификация java языка для getModifier():
Если базовый класс является классом массива, то его общедоступные, частные и защищенные модификаторы такие же, как у его типа компонента. Если этот класс представляет примитивный тип или пустоту, его общедоступный модификатор всегда прав, а его защищенные и частные модификаторы всегда ложны
Теперь значения других модификаторов не определяются этой спецификацией, например, АБСТРАКТ.
Из таблицы JVMS 4.1-A:
ACC_ABSTRACT 0x0400 Объявленный реферат; не должны создаваться.