Uro*_*s K 5 java reflection groovy annotations
是否可以在运行时更改字段注释值?
我可以访问这些值,但无法找到更改它们的方法.
可以访问:
Article.class.declaredFields.find {it.name="annotatedField"}.declaredAnnotations
Run Code Online (Sandbox Code Playgroud)
我认为除了Field(或Object)之外,最好保持对Annotation对象的引用,并在更改其值时更新Annotation引用.这样,当Class.java中的注释实现发生更改时,您的代码就不太可能中断.
问题注释中链接的答案对于处理包含单个元素的注释很有用,但如果您需要设置多个元素,则这是一个使用代理的更通用的解决方案:
import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Test {
public static void main(String[] args) throws Exception {
Foo foo = new Foo();
Field field = foo.getClass().getDeclaredFields()[0];
Anno anno = field.getAnnotation(Anno.class);
System.out.println(String.format("Old properties: %s, %s, %s", anno.value(), anno.bar(), anno.barr()));
Anno anno2 = (Anno) setAttrValue(anno, Anno.class, "value", "new");
System.out.println(String.format("New properties: %s, %s, %s", anno2.value(), anno2.bar(), anno2.barr()));
Anno anno3 = (Anno) setAttrValue(anno2, Anno.class, "bar", "new bar");
System.out.println(String.format("New properties: %s, %s, %s", anno3.value(), anno3.bar(), anno3.barr()));
}
public static Annotation setAttrValue(Annotation anno, Class<? extends Annotation> type, String attrName, Object newValue) throws Exception {
InvocationHandler handler = new AnnotationInvocationHandler(anno, attrName, newValue);
Annotation proxy = (Annotation) Proxy.newProxyInstance(anno.getClass().getClassLoader(), new Class[]{type}, handler);
return proxy;
}
}
class AnnotationInvocationHandler implements InvocationHandler {
private Annotation orig;
private String attrName;
private Object newValue;
public AnnotationInvocationHandler(Annotation orig, String attrName, Object newValue) throws Exception {
this.orig = orig;
this.attrName = attrName;
this.newValue = newValue;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// "override" the return value for the property we want
if (method.getName().equals(attrName) && args == null)
return newValue;
// keep other properties and methods we want like equals() and hashCode()
else {
Class<?>[] paramTypes = toClassArray(args);
return orig.getClass().getMethod(method.getName(), paramTypes).invoke(orig, args);
}
}
private static Class<?>[] toClassArray(Object[] arr) {
if (arr == null)
return null;
Class<?>[] classArr = new Class[arr.length];
for (int i=0; i<arr.length; i++)
classArr[i] = arr[i].getClass();
return classArr;
}
}
class Foo {
@Anno(value="old", bar="bar", barr="barr")
public Object field1;
}
@Retention(RetentionPolicy.RUNTIME)
@interface Anno {
String value();
String bar();
String barr();
}
Run Code Online (Sandbox Code Playgroud)
节目输出:
Old properties: old, bar, barr
New properties: new, bar, barr
New properties: new, new bar, barr
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
13955 次 |
| 最近记录: |