如何创建批注的实例

2022-08-31 13:59:25

我正在尝试做一些Java注释魔术。我必须说,我仍然在追赶注释技巧,某些事情对我来说仍然不太清楚。

所以。。。我有一些带注释的类,方法和字段。我有一个方法,它使用反射对类运行一些检查,并将一些值注入到类中。这一切都很好。

但是,我现在面临的情况是,我需要一个注释的实例(可以这么说)。所以。。。注释不像常规接口,你不能对类进行匿名实现。我明白了。我在这里查看了一些关于类似问题的帖子,但我似乎无法找到我所寻找的答案。

我基本上希望获得注释的实例,并能够使用反射(我想)设置其中的一些字段。有没有办法做到这一点?


答案 1

嗯,这显然没什么那么复杂。真!

正如一位同事所指出的,您可以简单地创建注释的匿名实例(像任何界面一样),如下所示:

我的注释:

public @interface MyAnnotation
{

    String foo();

}

调用代码:

class MyApp
{
    MyAnnotation getInstanceOfAnnotation(final String foo)
    {
        MyAnnotation annotation = new MyAnnotation()
        {
            @Override
            public String foo()
            {
                return foo;
            }

            @Override
            public Class<? extends Annotation> annotationType()
            {
                return MyAnnotation.class;
            }
        };

        return annotation;
    }
}

感谢马丁·格里戈罗夫


答案 2

正如Gunnar的答案所建议的那样,代理方法已经在GeantyRef中实现:

Map<String, Object> annotationParameters = new HashMap<>();
annotationParameters.put("name", "someName");
MyAnnotation myAnnotation = TypeFactory.annotation(MyAnnotation.class, annotationParameters);

这将生成一个注释,该注释等效于您从以下位置获得的内容:

@MyAnnotation(name = "someName")

以这种方式生成的注释实例的行为将与 Java 通常生成的注释实例相同,并且它们已经正确实现以实现兼容性,因此没有奇怪的警告,例如直接实例化注释,如在接受的答案中。事实上,JDK内部使用相同的方法:sun.reflect.annotation.AnnotationParser#annotationForMaphashCodeequals

库本身很小,没有依赖关系(也不依赖于JDK内部API)。

披露:我是GeantyRef背后的开发人员。