Вот как будет выглядеть обычное объявление интерфейса:
public interface Example {
String method();
}
Обратите внимание, что когда были выпущены аннотации, функции java «методы по умолчанию для интерфейсов» еще не было. Ключевое слово default
уже существует (и существует с java 1.0) исключительно как вещь, которую вы можете поместить в блок переключателя, поскольку 'case' для 'он не соответствует ни одному из вариантов'.
Так выглядит определение интерфейса аннотации:
public @interface Example {
String method();
}
или, если задействованы значения по умолчанию:
public @interface Example {
String method() default "";
}
Обратите внимание на то, насколько мудрый синтаксический анализ не имеет разницы между этими двумя, другие чем символ "@". В случае «по умолчанию»; да, это совершенно новое, но, глядя только на это, это не выглядит странно. Скобки, но не этот бит.
Причина, по которой это делается таким образом, состоит в том, чтобы не «взорвать» синтаксический анализ. С момента появления информации о модулях в java9, если вы хотите написать синтаксический анализатор для java, вам в основном НЕОБХОДИМ анализатор "переключения режимов на лету"; «спецификация языка» для файла модуля сильно отличается.
Но это большой шаг; подавляющее большинство библиотек синтаксического анализатора плохо справляются с этим, они не могут переключать грамматику в середине анализа исходного файла.
Даже если я могу щелкнуть пальцами и сломать java ( что, чтобы быть ясным, java обычно не делает: обновление языка, чтобы существующий код больше не компилировался или не означал что-то еще, - большой шаг, который очень редко делается по очевидным причинам. Однако это ограничивает дизайн языка. стоимость того, чтобы быть самым популярным языком в мире *) ... здесь есть преимущества.
Работа аннотаций заключается в том, что, если вы их во время выполнения получаете, они действуют как объект, являющийся экземпляром интерфейс аннотации:
Example foo = Class.forName("foo.bar.Baz").getAnnotation(Example.class);
System.out.println(foo.method());
Обратите внимание, что это не foo.method
. Это foo.method()
. И тому есть другие причины: поля в java - второсортные граждане. Вы не можете поместить их в ссылки на лямбда-методы (ClassName::methodName
является допустимым java; для полей такого нет), они не наследуются, вы не можете помещать их в интерфейсы (поля в интерфейсах автоматически публикуются c , final и stati c, т. е. константы. Они не определяют требования к какому-либо реализующему классу, в отличие от методов в интерфейсах). Это означает, что поля как общий принцип не используются в API publi c в java. Было бы странно, если бы в этом случае они были бы такими. * определение.
*) Плюс-минус несколько мест.