2017-01-03 5 views
1

Как читать аннотацию, объявленную над объектом.Как читать аннотацию, объявленную над объектом Java?

Для например

Аннотация:

AuthorInfo.java

@Retention(RetentionPolicy.RUNTIME) 
@Target(ElementType.FIELD) 
public @interface AuthorInfo { 
    String author() default "Dushyant Kumar"; 
    String login() default "dushyantashu"; 
} 

То, что я пытаюсь сделать:

Book.java

@Data 
public class Book { 
    private int serialNo; 
    private String review; 
} 

Main.java

public class Main { 

    @AuthorInfo (
      author = "Barry Allen", 
      login = "theflash" 
    ) 
    private static Book book = new Book(); 

    public static void main(String[] args) { 
     showAnnotation(book); 
    } 

    private static void showAnnotation(Object object) { 
     // How to get values of annotation declared over this object. 
    } 
} 

Моего UseCase заключается в создании этого общего showAnnotation() метода, поэтому пары являются Object. Как достичь этого? Из того, что я изучил, я только получил способы прочитать аннотацию, если она объявлена ​​над классом или объявлена ​​над членом класса. Разве нет способа, с помощью которого объект может быть прочитан, если какая-либо аннотация присутствует над ним?

Thanks

+3

Аннотации - это статическая информация о типах и элементах. Они не объявляются «над этим объектом». Вы можете прочитать его через 'Main.class.getDeclaredField (« book »). GetAnnotation (AuthorInfo.class)', поскольку он является свойством * field *, а не экземпляром 'Book'. Тот же экземпляр «Книга» может ссылаться на разные поля, имеющие совершенно разные аннотации. – Holger

+0

@Holger Это имеет смысл, поэтому единственный способ, которым я мог бы иметь разные значения аннотаций над объектами того же класса, - иметь их как членов какого-либо другого класса. Это правильно? – dushyantashu

+2

Поскольку вы аннотируете поля, эти поля могут быть в любом классе, который вам нужен, включая тот же класс, что и их объявленный тип, т. Е. Вы можете иметь аннотированные поля типа «Книга» в классе «Книга».Тем не менее, это не связано с ссылочным экземпляром; несколько полей могут ссылаться на один и тот же экземпляр, или поля могут быть «null», все это не имеет значения, аннотации - это просто свойство полей. И где смысл в попытке переносить конкретные данные в аннотации? Почему бы не объявить обычный 'AuthorInfo' класс и обычный член этого типа в' Book'? – Holger

ответ

0

Вы можете получить класс объекта, а затем изучить его. Via Reflection вы также можете получить свои поля и методы и проверить, есть ли на нем аннотации.

+1

Класс объекта «Книга», и этот класс не имеет аннотаций ... – Holger

+0

Я вижу @Data. Итак, где аннотация? Аннотации - это статическая информация, не зависящая от экземпляров. – Rubasace

+0

Это неотъемлемая проблема вопроса. Если все, что у вас есть, является экземпляром «Книга», в сфере видимости нет аннотации. Ну, действительно, есть '@ Data', который не несет никакой информации, но вопрос, очевидно, связан с' @ AuthorInfo', который предназначен для связи с книгой, но аннотация не работает таким образом. – Holger

0

Вы можете попробовать generics и reflection. Предположим, что Book класс помечается AuthorInfo, как показано ниже:

@AuthorInfo(author = "Ram", login = "ram") 
public class Book { 

} 

Предположим, если вы хотите знать, является ли AuthorInfo присутствует в объекте Book, вы можете сделать, как показано ниже. Это прямое решение, чтобы узнать, присутствует ли конкретная аннотация в объекте.

public class TestAnnotation { 

    public static void main(String[] args) { 
     Book book = new Book(); 
     showAnnotation(book); 

    } 

    private static <T> void showAnnotation(T t) { 
     Class<? extends Object> aClass = t.getClass(); 
     if (aClass.isAnnotationPresent(AuthorInfo.class)) { 
      System.out.println("AuthorInfo annotation present"); 
      AuthorInfo authorInfo = aClass.getAnnotation(AuthorInfo.class); 
      System.out.println(authorInfo.author()); 
      System.out.println(authorInfo.login()); 
     } 

    } 
} 

Предположим, если вы хотите знать все аннотации на этот объект, то, как показано ниже помогает:

private static <T> void showAnnotation(T t) { 
    Class<? extends Object> aClass = t.getClass(); 
    for (Annotation annotation : aClass.getAnnotations()) { 
     System.out.println(annotation.toString()); 
    } 
} 
+0

Нет никакой точки в общей сигнатуре типа ' void showAnnotation (T t)'. Он не дает преимуществ над 'void showAnnotation (Object t)'. – Holger

+0

Без сомнения. Согласовано – Sridhar

0

Аннотации могут быть считаны с помощью Reflection API. Как

Class<Main> clazz = Main.class; 
Method[] methods = clazz.getDeclaredMethods(); 
Field[] fields = clazz.getDeclaredFields(); 
for (Method method : methods) { 
    Annotation[] annotation = method.getDeclaredAnnotations(); 
} 
for (Field field : fields) { 
    //This will get @AuthorInfo annotation on book 
    Annotation[] annotation = field.getDeclaredAnnotations(); 
    //This will get @Data annotation on Book class 
    Annotation[] annotationsOnFieldClass = field.getClass().getDeclaredAnnotations(); 
} 
clazz.getDeclaredAnnotations();