Нулевое значение по умолчанию для полей аннотации в Java - PullRequest
0 голосов
/ 22 января 2020

Я создаю пользовательскую аннотацию

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyFramework {

    public Integer index() default null; // Compiler complains here

}

Компилятор жалуется, что null недопустимо. Я не хочу делать индексное поле примитивного типа int, так как это не имеет смысла. Есть ли способ получить значение по умолчанию null для полей аннотации?

Ответ на Ошибка установки нулевого значения по умолчанию для поля аннотации упоминание о типе Class, поэтому решения работать, но не для Integer, Double et c.

1 Ответ

1 голос
/ 23 января 2020

Нельзя использовать null в качестве значения по умолчанию (или не по умолчанию). Использование null категорически запрещено Java Спецификацией языка (JLS). Из §9.6.2 JLS :

Ошибка времени компиляции, если тип элемента не соизмерим ( §9.7 ) с указанным значением по умолчанию.

И из §9.7.1 JLS :

Это является ошибкой времени компиляции, если тип элемента не соизмерим со значением элемента. Тип элемента T соизмерим со значением элемента V в том и только в том случае, если выполняется одно из следующих значений :

  • T - тип массива E[] и либо:

    • Если V является Условным выражением или Аннотация , то V соответствует E; или
    • Если V является ElementValueArrayInitializer , то каждое значение элемента, которое содержит V, соизмеримо с E.

      ElementValueArrayInitializer похож на обычный инициализатор массива (§10.6), за исключением того, что ElementValueArrayInitializer может синтаксически содержать аннотации, а также выражения и вложенные инициализаторы. Однако вложенные инициализаторы не являются семантически допустимыми в ElementValueArrayInitializer, поскольку они никогда не соизмеримы с элементами с массивами в объявлениях типов аннотаций (типы вложенных массивов недопустимы).

  • T не является типом массива, а тип V совместим с назначением (§5.2) с T и:

    • Если T является примитивным типом или String, тогда V является константным выражением (§15.28).
    • Если T равно Class или вызов Class (§4.5), тогда V является литералом класса (§15.8.2).
    • Если T является типом перечисления (§8.9), то V является константой перечисления (§8.9.1).
    • V не является null.

Обратите внимание, что если T не является типом массива или типом аннотации, значение элемента должно быть условным выражением (§15.25). Использование ConditionalExpression, а не более общего производства, такого как Expression, является трюком syntacti c для предотвращения выражений присваивания в качестве значений элементов. Поскольку выражение присваивания не является константным выражением, оно не может быть соразмерным значением элемента для примитива или элемента с типом String.

[...]

Именно эта последняя точка, "V - это не null", это причина вашей ошибки компиляции.

Если вы хотите значение по умолчанию, которое означает "не установлено", используйте ненулевое значение дозорного Например, если отрицательное число никогда не является допустимым значением, вы можете использовать любое отрицательное число (например, -1, Integer.MIN_VALUE, et c.) В качестве значения по умолчанию. Например:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyFramework {

  // note the "public" modifier is implicitly added
  Integer index() default Integer.MIN_VALUE;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...