开发者社区> 问答> 正文

如何在运行时编辑方法注释属性?

我有一个用于在运行时编辑地图键的简单注释:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface UpdateKey
{
    String oldKey() default "";    //The key that needs to be replaced

    String newKey() default "";    //The new key

}

我在某些类的方法上使用它:

public class CustomMap
{
    @UpdateKey(oldKey = "description", newKey = "productName")
    public void editMap(Map<String,String> map) throws NoSuchMethodException
    {
        //get the annotation values
        UpdateKey updateKey = this.getClass().getMethod("editMap").getAnnotation(UpdateKey.class);

        //save value and delete old key
        Object obj = map.remove(updateKey.oldKey());

        //set the value to the new key
        map.put(updateKey.newKey(),obj);
    }
}

但是在调用该方法之前似乎没有任何操作来操纵此注释,我已经尝试过:

 // get the edit map method
        Method method = CustomMap.class.getDeclaredMethod("editMap");

        // get the annotation 
        UpdateKey updateKeyAnnotation = method.getDeclaredAnnotation(UpdateKey.class);

        Object handler = Proxy.getInvocationHandler(updateKeyAnnotation);

        //this is retrieving the reflection class fields NOT my annotation fields
        sout(handler.getClass().getDeclaredFields());

        Field f;

        //of course this will fail since there is no oldKey field in the reflection class
        f = handler.getClass().getDeclaredField("oldKey");  

问题来源:Stack Overflow

展开
收起
montos 2020-03-26 11:03:43 782 0
1 条回答
写回答
取消 提交回答
  • 伙计,您距离解决方案仅2步之遥。检索调用处理程序后,必须更改它的字段memberValues。这是完整的代码:

    import java.lang.annotation.*;
    import java.lang.reflect.Field;
    import java.lang.reflect.Method;
    import java.lang.reflect.Proxy;
    import java.util.Arrays;
    import java.util.HashMap;
    import java.util.Map;
    
    public class NewApp {
    
        public static void main(String[] args) throws NoSuchMethodException, NoSuchFieldException, IllegalAccessException {
    
    
            // get the edit map method
            Method method = CustomMap.class.getDeclaredMethod("editMap", Map.class);
    
            // get the annotation
            UpdateKey updateKeyAnnotation = method.getDeclaredAnnotation(UpdateKey.class);
            System.out.println("current annotation: " + updateKeyAnnotation);
    
            Object handler = Proxy.getInvocationHandler(updateKeyAnnotation);
    
            System.out.println(Arrays.toString(handler.getClass().getDeclaredFields()));
    
            // field memberValues contains annotation attributes and their values
            // just modify it
            Field memberValues = handler.getClass().getDeclaredField("memberValues");
            memberValues.setAccessible(true);
            System.out.println(memberValues.get(handler));
    
            Map<String, String> annotationAttributes = new HashMap<>();
            annotationAttributes.put("newKey", "otherProduct");
            annotationAttributes.put("oldKey", "otherDescription");
            memberValues.set(handler, annotationAttributes);
    
    
            System.out.println("changed annotation: " + updateKeyAnnotation);
        }
    }
    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    @interface UpdateKey {
        String oldKey() default "";    //The key that needs to be replaced
    
        String newKey() default "";    //The new key
    }
    
    class CustomMap {
    
        @UpdateKey(oldKey = "description", newKey = "productName")
        public void editMap(Map<String, String> map) throws NoSuchMethodException {
            //get the annotation values
            UpdateKey updateKey = this.getClass().getMethod("editMap").getAnnotation(UpdateKey.class);
    
            //save value and delete old key
            Object obj = map.remove(updateKey.oldKey());
    
            //set the value to the new key
            map.put(updateKey.newKey(), obj.toString());
        }
    }
    

    此代码的输出

    current annotation: @UpdateKey(newKey=productName, oldKey=description)
    [private static final long sun.reflect.annotation.AnnotationInvocationHandler.serialVersionUID, private final java.lang.Class sun.reflect.annotation.AnnotationInvocationHandler.type, private final java.util.Map sun.reflect.annotation.AnnotationInvocationHandler.memberValues, private transient volatile java.lang.reflect.Method[] sun.reflect.annotation.AnnotationInvocationHandler.memberMethods, static final boolean sun.reflect.annotation.AnnotationInvocationHandler.$assertionsDisabled]
    {newKey=productName, oldKey=description}
    changed annotation: @UpdateKey(oldKey=otherDescription, newKey=otherProduct)
    

    回答来源:Stack Overflow

    2020-03-26 11:04:32
    赞同 展开评论 打赏
问答分类:
问答地址:
问答排行榜
最热
最新

相关电子书

更多
《0代码搭应用》 立即下载
不止代码 立即下载
低代码开发师(初级)实战教程 立即下载