Чтобы скомпилировать тип enum
, необходимо пометить класс флагом ACC_ENUM
в флагах доступа к классу.
Далее, для каждой константы,вам необходимо создать соответствующее поле public static final
, которое также помечено ACC_ENUM
в флагах доступа к полю.
Затем необходим инициализатор класса (метод no-arg void
с именем <clinit>
), который создает экземпляры и присваивает их полям.
Но этого недостаточно. Запомните спецификацию языка , которая определяет существование двух неявно объявленных методов
/**
* Returns an array containing the constants of this enum
* type, in the order they're declared. This method may be
* used to iterate over the constants as follows:
*
* for(E c : E.values())
* System.out.println(c);
*
* @return an array containing the constants of this enum
* type, in the order they're declared
*/
public static E[] values();
/**
* Returns the enum constant of this type with the specified
* name.
* The string must match exactly an identifier used to declare
* an enum constant in this type. (Extraneous whitespace
* characters are not permitted.)
*
* @return the enum constant with the specified name
* @throws IllegalArgumentException if this enum type has no
* constant with the specified name
*/
public static E valueOf(String name);
Это обязанность компилятора, соответственно. инструмент генерации байт-кода для вставки их реализации в определенный тип перечисления. Обратите внимание, что, несмотря на то, что они сгенерированы компилятором, эти два метода не должны быть помечены как синтетические .
Спецификация не описывает, как Reflection будет собирать свою информацию. Он может перебирать отмеченные поля и читать их, собирать массив или просто вызывать метод values()
определенного типа. Таким образом, вы не можете опустить ни один из этих артефактов и не можете реализовать метод values()
, просто делегировав Class.getEnumConstants()
.