Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/312.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何读取在Java对象上声明的注释?_Java_Object_Reflection_Annotations - Fatal编程技术网

如何读取在Java对象上声明的注释?

如何读取在Java对象上声明的注释?,java,object,reflection,annotations,Java,Object,Reflection,Annotations,如何读取在对象上声明的注释 例如 注释: AuthorInfo.java 我想做的是: Book.java Main.java 我的用例是生成这个通用的showAnnotation()方法,这就是为什么param是Object。如何做到这一点?根据我所探索的,我只有在注释是在类上声明的,或者是在类的成员上声明的情况下才能读取注释。如果某个对象上有注释,那么该对象是否可以被读取 谢谢您可以检索对象类,然后浏览它。通过反射,您还可以获取其字段和方法,并检查是否有注释 您可以尝试使用泛型和反射。假设B

如何读取在对象上声明的注释

例如

注释:

AuthorInfo.java

我想做的是:

Book.java

Main.java

我的用例是生成这个通用的
showAnnotation()
方法,这就是为什么param是
Object
。如何做到这一点?根据我所探索的,我只有在注释是在类上声明的,或者是在类的成员上声明的情况下才能读取注释。如果某个对象上有注释,那么该对象是否可以被读取


谢谢

您可以检索对象类,然后浏览它。通过反射,您还可以获取其字段和方法,并检查是否有注释

您可以尝试使用
泛型
反射
。假设
Book
类使用
AuthorInfo
注释,如下所示:

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

}
假设您想知道
Book
的对象中是否存在
AuthorInfo
,可以执行以下操作。这是了解对象中是否存在特定注释的直接解决方案

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());
        }

    }
}
公共类测试说明{
公共静态void main(字符串[]args){
书=新书();
展览注释(书籍);
}
专用静态void showAnnotation(T){

类注释可以使用
反射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();
Class clazz=Main.Class;
方法[]methods=clazz.getDeclaredMethods();
Field[]fields=clazz.getDeclaredFields();
用于(方法:方法){
Annotation[]Annotation=method.getDeclaredAnnotations();
}
用于(字段:字段){
//这将在书本上获得@AuthorInfo注释
Annotation[]Annotation=field.getDeclaredAnnotations();
//这将在Book类上获得@Data注释
Annotation[]annotationsOnFieldClass=field.getClass().getDeclaredAnnotations();
}
clazz.getDeclaredAnnotations();

Annotation是关于类型和成员的静态信息。它们不会声明为“在此对象上”。您可以通过
Main.class.getDeclaredField(“book”).getAnnotation(AuthorInfo.class)读取它
,因为它是字段的属性,而不是
Book
实例。相同的
Book
实例可以被具有完全不同注释的不同字段引用。@Holger这是有意义的,所以我可以对同一类的对象具有不同注释值的唯一方法是将它们作为其他类的成员。是这样吗?由于您对字段进行了注释,这些字段可以位于您想要的任何类中,包括与其声明类型相同的类,也就是说,在类
Book
中可以有
Book
类型的注释字段。但是,这与引用的实例没有关联;多个字段可能引用同一实例,或者字段可以是
null
,这一切都无关紧要,注释只是字段的一个属性。在注释中尝试携带实例特定数据的意义何在?为什么不在
Book
中声明一个普通
AuthorInfo
类和该类型的普通成员?@Holger谢谢!我更喜欢ned继续使用annotation,因为我需要它被许多其他类使用。通过使它成为一个普通类,我需要添加这些类,我不应该这样做,因为它对应于不同的业务逻辑。因此我可以选择创建类似于此AuthorInfo和不同类的映射,或者创建类似于c可以在这些类上定义一个包装器,或者在这些类上定义一个包装器,这些类也将包含AuthorInfo。谢谢,我认为在类声明上定义注释更有意义。它没有比指向
Book
实例和
AuthorInfo
实例以建立关联的普通对象更有意义(当您无法更改
书籍
类时)。必须更改代码才能将另一本书添加到应用程序的数据中是一个甚至不值得讨论的设计…对象的类是
book
,而这个类没有注释…我看到@data。那么注释在哪里?注释是静态信息,不依赖实例。这是问题的固有问题选项。如果您只有一本
@Book
实例,那么范围中就没有注释。哦,确实有
@Data
,它不携带任何信息,但问题显然是关于
@AuthorInfo
的,它是要与一本书关联的,但是注释不是这样工作的。好的,您可以检查给定的对象ct如果主类(或任何其他受控范围)中存在具有相同类的字段。如果有,您可以检索该字段批注,因此,每当您收到一本书时,您都会返回@AuthorInfo,如果它有效,我可以更新我的答案,甚至提供一些示例,但这是一个非常糟糕的设计。它不能保护您免受错误的影响,就像多个字段引用同一对象一样,它需要昂贵的搜索nd是不可扩展的,因为您必须更改应用程序代码以合并新实例或更新数据。从实例映射到关联数据的唯一的
HashMap
,在所有方面都是优越的(无论出于何种原因,假设仅将数据存储在实例本身不是一个选项)。像
void showAnnotation(T)
这样的通用签名没有任何意义。它与
void showAnnotation(Object T)
相比没有任何好处。
@AuthorInfo(author = "Ram", login = "ram")
public class 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());
    }
}
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();