Java 如何使用反射获取注解类名、属性值

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20362493/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-13 01:23:20  来源:igfitidea点击:

How to get annotation class name, attribute values using reflection

javareflectionannotations

提问by Jianwu Chen

I know if we know the annotation class, we can easily get the specific annotation and access its attribute. For example:

我知道如果我们知道注解类,我们可以很容易地得到具体的注解并访问它的属性。例如:

field.getAnnotation(Class<T> annotationClass) 

Which will return a reference of specific annotation interface, so you can easily access its values.

这将返回特定注释接口的引用,因此您可以轻松访问其值。

My question is if I have no pre knowledge about the particular annotations class. I just want to use reflection to get all the annotation class name and their attributes at run-time for the purpose of dumping the class information for example as a JSON file. How can I do it in an easy way.

我的问题是我是否对特定的注释类没有预先了解。我只想使用反射在运行时获取所有注释类名称及其属性,以便将类信息转储为 JSON 文件。我怎样才能以简单的方式做到这一点。

Annotation[] field.getAnnotations();

This method will only return dynamic proxies of the annotation interfaces.

这个方法只会返回注解接口的动态代理。

采纳答案by kapex

Contrary to what one might expect, the elements of an annotation are not attributes - they are actually methods that return the provided value or a default value.

与人们所期望的相反,注解的元素不是属性——它们实际上是返回提供值或默认值的方法。

You have to iterate through the annotations' methods and invoke them to get the values. Use annotationType()to get the annotation's class, the object returned by getClass()is just a proxy.

您必须遍历注释的方法并调用它们以获取值。使用annotationType()获得注释的类,返回的对象getClass()只是一个代理。

Here is an example which prints all elements and their values of the @Resourceannotation of a class:

这是一个打印@Resource类注释的所有元素及其值的示例:

@Resource(name = "foo", description = "bar")
public class Test {

    public static void main(String[] args) throws Exception {

        for (Annotation annotation : Test.class.getAnnotations()) {
            Class<? extends Annotation> type = annotation.annotationType();
            System.out.println("Values of " + type.getName());

            for (Method method : type.getDeclaredMethods()) {
                Object value = method.invoke(annotation, (Object[])null);
                System.out.println(" " + method.getName() + ": " + value);
            }
        }

    }
}

Output:

输出:

Values of javax.annotation.Resource
 name: foo
 type: class java.lang.Object
 lookup: 
 description: bar
 authenticationType: CONTAINER
 mappedName: 
 shareable: true

Thanks to Aaronfor pointing out the you need to cast the nullargument to avoid warnings.

感谢Aaron指出您需要强制转换null参数以避免警告。

回答by Aaron

Just to follow up on the answer above (I don't have enough rep to reply to it):

只是为了跟进上面的答案(我没有足够的代表来回复它):

method.invoke(annotation, null)

should be changed to the following, otherwise it throws an exception:

应该改为如下,否则抛出异常:

method.invoke(annotation, (Object[])null) or method.invoke(annotation, new Object[0])