car*_*ing 52 java reflection annotations
我正在尝试做一些Java注释魔术.我必须说我仍在追赶注释技巧,而且某些事情对我来说仍然不太清楚.
所以...我有一些带注释的类,方法和字段.我有一个方法,它使用反射对类运行一些检查并将一些值注入到类中.一切正常.
但是,我现在面临的情况是我需要一个注释的实例(可以这么说).所以...注释不像常规接口,你不能做一个类的匿名实现.我知道了.我在这里看了一些关于类似问题的帖子,但我似乎无法找到我正在寻找的答案.
我基本上想得到一个注释的实例,并能够使用反射设置它的一些字段(我想).有没有办法做到这一点?
car*_*ing 64
好吧,显然没有什么比这更复杂了.真!
正如同事所指出的,你可以简单地创建一个匿名的注释实例(就像任何接口一样):
MyAnnotation:
public @interface MyAnnotation
{
String foo();
}
Run Code Online (Sandbox Code Playgroud)
调用代码:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
致Martin Grigorov的学分.
kaq*_*qao 11
Gunnar的答案中建议的代理方法已在GeAnTyRef中实现:
Map<String, Object> annotationParameters = new HashMap<>();
annotationParameters.put("name", "someName");
MyAnnotation myAnnotation = TypeFactory.annotation(MyAnnotation.class, annotationParameters);
Run Code Online (Sandbox Code Playgroud)
这将产生一个等同于你得到的注释:
@MyAnnotation(name = "someName")
Run Code Online (Sandbox Code Playgroud)
这种方式生产的注释情况下将采取行动等同于在Java正常生产的那些,他们hashCode
和equals
已经正确实施的兼容性,所以没有离奇的注意事项就像在实例化注释作为公认的答案.事实上,JDK内部使用相同的方法:sun.reflect.annotation.AnnotationParser#annotationForMap.
库本身很小,没有依赖性.
披露:我是GeAnTyRef背后的开发人员.
Rav*_*wal 11
您还可以绝对愚蠢地(但简单地)创建一个虚拟注释目标并从那里获取它
@MyAnnotation(foo="bar", baz=Blah.class)
private static class Dummy {}
Run Code Online (Sandbox Code Playgroud)
和
final MyAnnotation annotation = Dummy.class.getAnnotation(MyAnnotation.class)
Run Code Online (Sandbox Code Playgroud)
创建方法/参数目标注释实例可能会更复杂一些,但这种方法的优点是可以像 JVM 通常那样获取注释实例。不用说,它是尽可能简单的。
你可以使用sun.reflect.annotation.AnnotationParser.annotationForMap(Class, Map)
:
public @interface MyAnnotation {
String foo();
}
public class MyApp {
public MyAnnotation getInstanceOfAnnotation(final String foo) {
MyAnnotation annotation = AnnotationParser.annotationForMap(
MyAnnotation.class, Collections.singletonMap("foo", "myFooResult"));
}
}
Run Code Online (Sandbox Code Playgroud)
缺点:来自sun.*
更高版本的类可能会发生更改(尽管此方法自Java 5以来具有相同的签名)并且不适用于所有Java实现,请参阅此讨论.
如果这是一个问题:您可以使用自己的代理创建一个通用代理InvocationHandler
- 这正是AnnotationParser
内部正在为您做的事情.或者您使用自己在此MyAnnotation
定义的实现.在这两种情况下,您都应该记住实施,并且结果是专门记录的.annotationType()
equals()
hashCode()
java.lang.Annotation
归档时间: |
|
查看次数: |
25962 次 |
最近记录: |