Я не понимаю, почему в аннотациях Java нет наследования, так же как и в классах Java. Я думаю, это было бы очень полезно.
Например: я хочу знать, является ли данная аннотация валидатором. С наследованием я мог бы рефлексивно перемещаться по суперклассам, чтобы знать, расширяет ли эта аннотация a ValidatorAnnotation
. Иначе как мне этого добиться?
Итак, кто-нибудь может дать мне причину этого дизайнерского решения?
java
inheritance
annotations
sinuhepop
источник
источник
java.lang.annotation.Annotation
, т. Е. Любая аннотация,instanceof
хотя этот факт явно не объявлен.Ответы:
О причине, по которой он не был спроектирован таким образом, вы можете найти ответ в FAQ по JSR 175 Design, где говорится:
Так что, да, я думаю, причина в том, что это просто ПОЦЕЛУЙ. Во всяком случае, кажется, что эта проблема (наряду со многими другими) рассматривается как часть JSR 308 , и вы даже можете найти альтернативный компилятор с этой функциональностью, уже разработанной Матиасом Рикеном .
источник
Расширяемые аннотации эффективно добавили бы бремя определения и поддержки другой системы типов. И это будет довольно уникальная система типов, поэтому вы не сможете просто применить парадигму типа ОО.
Продумайте все вопросы, когда вы вводите полиморфизм и наследование в аннотацию (например, что происходит, когда поданнотация изменяет спецификации метааннотации, такие как сохранение?)
И все это добавляет сложности для какого варианта использования?
Вы хотите знать, относится ли данная аннотация к категории?
Попробуй это:
Как вы можете видеть, вы можете легко группировать и классифицировать аннотации без лишних усилий, используя предоставленные средства.
Итак, поцелуй является причиной отказа от введения системы типов мета-типов в язык Java.
[ps edit]
Я использовал String просто для демонстрации и ввиду открытой метааннотации. Для вашего собственного данного проекта вы, очевидно, можете использовать перечисление типов категорий и указать несколько категорий («множественное наследование») для данной аннотации. Обратите внимание, что значения являются полностью поддельными и только для демонстрационных целей:
источник
@Target(ElementType.ANNOTATION_TYPE) @Retention(RetentionPolicy.RUNTIME) @interface C {}; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @C public @interface F {} class a{ @F public void S() {} } @Test public void blahTest() throws NoSuchMethodException { Method m = a.class.getMethod("S"); System.out.println(m.isAnnotationPresent(C.class)); }
В некотором смысле у вас уже есть это с аннотациями - мета аннотации. Если вы аннотируете аннотацию метаинформацией, это во многом эквивалентно расширению дополнительного интерфейса. Аннотации являются интерфейсами, поэтому полиморфизм на самом деле не вступает в игру, и поскольку они статичны по своей природе, динамическая диспетчеризация во время выполнения не может быть.
В вашем примере валидатора вы можете просто в аннотации получить аннотированный тип и посмотреть, имеет ли он метааннотацию валидатора.
Единственный вариант использования, который я мог видеть, что наследование помогло бы, это если бы вы хотели иметь возможность получать аннотации по супертипу, но это добавило бы целую кучу сложности, потому что у данного метода или типа могут быть две такие аннотации, Это означает, что массив должен быть возвращен вместо одного объекта.
Поэтому я думаю, что окончательный ответ заключается в том, что варианты использования являются эзотерическими и усложняют более стандартные варианты использования, что делает его не стоящим.
источник
Разработчики поддержки аннотаций Java сделали ряд «упрощений» в ущерб сообществу Java.
Отсутствие подтипов аннотаций делает многие сложные аннотации излишне уродливыми. Нельзя просто иметь атрибут внутри аннотации, который может содержать одну из трех вещей. Нужно иметь три отдельных атрибута, что смущает разработчиков и требует проверки во время выполнения, чтобы гарантировать, что используется только один из трех.
Только одна аннотация данного типа для каждого сайта. Это привело к совершенно ненужному шаблону аннотации коллекции. @Validation и @Validations, @Image и @Images и т. Д.
Второй исправляется в Java 8, но уже слишком поздно. Многие фреймворки были написаны на основе того, что было возможно в Java 5, и теперь эти бородавки API здесь, чтобы остаться надолго.
источник
Я мог бы опоздать на три года с ответом на этот вопрос, но я нашел его интересным, потому что я оказался в том же месте. Вот мой взгляд на это. Вы можете просматривать аннотации как Enums. Они предоставляют одностороннюю информацию - используйте ее или потеряете.
У меня была ситуация, когда я хотел симулировать GET, POST, PUT и DELETE в веб-приложении. Я так сильно хотел иметь «супер» аннотацию, которая называлась «HTTP_METHOD». Позже меня осенило, что это не имеет значения. Что ж, мне пришлось согласиться с использованием скрытого поля в форме HTML для идентификации DELETE и PUT (потому что POST и GET были доступны в любом случае).
На стороне сервера я искал скрытый параметр запроса с именем «_method». Если значение было PUT или DELETE, то оно переопределяет связанный метод HTTP-запроса. Сказав это, не имело значения, нужно ли мне расширять аннотацию, чтобы выполнить работу. Все аннотации выглядели одинаково, но на стороне сервера они обрабатывались по-разному.
Так что в вашем случае снимите зуд, чтобы продлить аннотации. Относитесь к ним как к «маркерам». Они «представляют» некоторую информацию и не обязательно «манипулируют» некоторой информацией.
источник
Одна вещь, о которой я мог подумать, это возможность иметь несколько аннотаций. Таким образом, вы можете добавить валидатор и более конкретную аннотацию в одном месте. Но я могу ошибаться :)
источник
Никогда не думал об этом, но ... кажется, что вы правы, с наследованием аннотаций проблем нет (по крайней мере, я не вижу проблем с этим).
О вашем примере с аннотацией 'validator' - тогда вы можете использовать подход 'meta-annotation' . Т.е. вы применяете определенную метааннотацию ко всему интерфейсу аннотации.
источник
та же проблема у меня. Нет, ты не можешь. Я «дисциплинировал» себя, чтобы писать свойства в аннотациях, чтобы соблюдать некоторые стандарты, поэтому снаружи, когда вы получаете аннотацию, вы можете «узнать», какой это вид аннотации, по свойствам, которые она имеет.
источник