Как расширить аннотацию Java?
В моем проекте я использую предопределенную аннотацию @With
:
@With(Secure.class)
public class Test { //....
Исходный код @With
:
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface With {
Class<?>[] value() default {};
}
Я хочу написать пользовательскую аннотацию @Secure
, которая автоматически помещает аннотацию Secure.class
в @With
. Как это сделать?
Что, если я это сделаю? Будет ли это работать?
@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {
}
Ответы
Ответ 1
Из спецификации языка Java Глава 9.6 Типы аннотаций:
Не разрешено предложение extends. (Типы аннотаций неявно расширяются annotation.Annotation
.)
Итак, вы не можете расширять аннотацию. вам нужно использовать какой-то другой механизм или создать код, который распознает и обрабатывает вашу собственную аннотацию. Spring позволяет группировать другие аннотации Spring в ваших собственных аннотациях. но, тем не менее, не расширяется.
Ответ 2
Как отметил Пиотрек, вы не можете расширять аннотации в смысле наследования. Тем не менее, вы можете создавать аннотации, которые объединяют другие:
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SuperAnnotation {
String value();
}
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface SubAnnotation {
SuperAnnotation superAnnotation();
String subValue();
}
Использование:
@SubAnnotation(subValue = "...", superAnnotation = @SuperAnnotation(value = "superValue"))
class someClass { ... }
Ответ 3
Как сделать аннотацию Secure
по умолчанию value()
?
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Secure {
Class<?>[] value() default { Secure.class };
}
Ответ 4
@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {
}
Это будет работать.
Ответ 5
Развернуть на Muhammad Abdurrahman ответ -
@With(Secure.class)
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface Secure {
}
Это работает не, но вы можете использовать его в сочетании с Spring AnnotationUtils.
См. этот SO ответ для примера.