Обнаружение существующих аннотаций внутри данного объекта, переданных в конструктор
Мой вопрос вкратце: как определить, присутствует ли аннотация java (и в нужном месте) для данного пользовательского класса/объекта.
Подробности "проблемы"
Допустим, у меня есть два класса java:
public class Line {
private List<Cell> cells;
public Line(Object... annotatedObjects) {
// check if annotations @Line and @Cell are present in annotatedObjects.
}
// getter/setter for cells.
}
public class Cell {
// some members
// some methods
}
Объект Line удерживает ячейки.
У меня также есть две аннотации, например:
public @interface Line {
// some stuff here
}
public @interface Cell {
// some stuff here
}
У меня также есть группа пользовательских классов (в этом примере будут два), которые содержат аннотации @Line и @Cell, которые я указал, например:
@Line(name="pqr", schema="three")
public class AUserClass {
@Cell
private String aString;
}
@Line(name="xyz", schema="four")
public class AnotherUserClass {
@Cell(name="birthday")
private Date aDate;
}
Проблема: когда я создаю экземпляр нового объекта Line, я хочу иметь возможность передавать пользовательские классы/объекты в конструктор Line. Конструктор Line затем выясняет, являются ли пройденные классы/объекты пользователем допустимыми классами, которые могут быть обработаны. Только пользовательские классы, которые имеют аннотацию @Line
для класса и по крайней мере одну аннотацию @Cell
для своих членов, являются допустимыми объектами, которые могут быть переданы в конструктор объекта Line.
Все остальные переданные объекты недействительны. Когда передается действительный объект пользователя, все доступные члены, помеченные как @Cell
в этом объекте, преобразуются в объекты Cell и добавляются в список ячеек.
Мои вопросы:
Спасибо за вашу любезную помощь!
Ответы
Ответ 1
Сначала вам нужно иметь политику хранения ваших аннотаций, чтобы вы могли читать их с отражением
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public static @interface Line {
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public static @interface Cell {
}
Во-вторых, вам нужно проверить, имеет ли класс аннотацию Line с isAnnotationPresent(annotationClass)
. Этот метод доступен из java.lang.Class
и java.lang.reflect.Field.
ПРИМЕЧАНИЕ: вам нужно получить поля, закрытые с помощью class.getDeclaredField(fieldName)
.
3.
Я не думаю, что вы можете сделать аннотацию, имеющую значение по умолчанию, основанное на имени свойства, но вы можете сделать имя необязательным, указав по умолчанию String name() default DEFAULT
и проверить это значение при итерации по полям и использовать значение, сохраненное в name()
или propertyName
Ответ 2
Q.1: возможно ли это обнаружить аннотации в этом объекте/классе во время выполнения и только для этого переданного объекта (я не хочу проверять аннотации в пути к классам!)?
Да, это очень возможно, используя isAnnotationPresent
@Deprecated
public class AnnotationDetection {
public static void main(String[] args) {
AnnotationDetection annotationDetection = new AnnotationDetection();
System.out.println(annotationDetection.getClass().isAnnotationPresent(Deprecated.class));
}
}
Примечание, что аннотация, которая ограничена для сохранения в Runtime
, будет доступна только,