如何在Java中更改运行时字段注释的值?

时间:2015-05-18 10:39:53

标签: java annotations

我需要在运行时从一个类更改(或删除整个)注释值。我从SO获得了这个问题,但这个解决方案只适用于类注释,而不适用于字段注释。知道怎么做到这一点?这样做的原因是在数据库模型定义类中进行微小更改以不使用enum字段,因为内存数据库没有像MySQL这样的数据类型。

这是在SO上找到的工作(部分)解决方案:

package annotations;

import java.lang.annotation.Annotation;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Field;
import java.lang.reflect.Proxy;
import java.util.Map;

public class AnnotationModification2 {

    public static void main(String[] args) throws Exception {
        Something annotation = (Something) Foobar.class.getAnnotations()[0];
        System.out.println("oldAnnotation = " + Foobar.class.getAnnotation(Something.class).someProperty());
        changeAnnotationValue(annotation, "someProperty", "another value");
        System.out.println("modifiedAnnotation = " + Foobar.class.getAnnotation(Something.class).someProperty());

        annotation = (Something) Foobar.class.getDeclaredField("name").getAnnotations()[0];

        System.out.println("oldAnnotation = " + annotation.someProperty());
        changeAnnotationValue(annotation, "someProperty", "another value");
        System.out.println("modifiedAnnotation = " + annotation.someProperty());

        System.out.println(Foobar.class.getDeclaredField("name").getAnnotation(Something.class).someProperty());
    }

    /**
     * Changes the annotation value for the given key of the given annotation to newValue and returns
     * the previous value.
     */
    @SuppressWarnings("unchecked")
    public static Object changeAnnotationValue(Annotation annotation, String key, Object newValue){
        Object handler = Proxy.getInvocationHandler(annotation);
        Field f;
        try {
            f = handler.getClass().getDeclaredField("memberValues");
        } catch (NoSuchFieldException | SecurityException e) {
            throw new IllegalStateException(e);
        }
        f.setAccessible(true);
        Map<String, Object> memberValues;
        try {
            memberValues = (Map<String, Object>) f.get(handler);
        } catch (IllegalArgumentException | IllegalAccessException e) {
            throw new IllegalStateException(e);
        }
        Object oldValue = memberValues.get(key);
        if (oldValue == null || oldValue.getClass() != newValue.getClass()) {
            throw new IllegalArgumentException();
        }
        memberValues.put(key,newValue);
        return oldValue;
    }

    @Something(someProperty = "some value")
    public static class Foobar {

        @Something(someProperty = "Old field value!")
        private String name;
    }

    @Retention(RetentionPolicy.RUNTIME)
    @interface Something {

        String someProperty();
    }
}

1 个答案:

答案 0 :(得分:0)

尝试使用&#34; getField&#34;方法:

Something annotation = (Something) Foobar.class.getField("name").getAnnotations()[0];