Java 运行时动态修改注解的属性值

  • Java 虚拟机使用的“真实”注释类的实例是动态代理的实例
  • Java 注解有一个名为 memberValues 的私有Map,其中存储了属性名称和属性值的k-v对
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface MyProperties {
    String value();

    String[] names() default {};
}
@Data
public class Pairs {
    @MyProperties("Jaemon")
    private String key;
    @MyProperties(value = "Answer", names = {"Answer", "AI"})
    private String value;

    @MyProperties("B.M")
    public void generate() {

    }
}
public class AnnoApp {

    @SuppressWarnings("unchecked")
    public static void main(String[] args) {
        System.out.println("修改前");
        for (Field field : Pairs.class.getDeclaredFields()) {
            MyProperties myProperties = field.getAnnotation(MyProperties.class);
            System.out.println(myProperties.value());
            System.out.println(Arrays.asList(myProperties.names()));
            System.out.println();
        }

        try {
            for (Field field : Pairs.class.getDeclaredFields()) {
                MyProperties myProperties = field.getAnnotation(MyProperties.class);
                // 获取注解的代理处理器
                InvocationHandler invocationHandler = Proxy.getInvocationHandler(myProperties);
                /**
                for (Field declaredField : invocationHandler.getClass().getDeclaredFields()) {
                    System.out.println(declaredField.getName());
                }
                */
                Field values = invocationHandler.getClass().getDeclaredField("memberValues");
                values.setAccessible(true);
                Map<String, Object> memberValues =(Map<String, Object>) values.get(invocationHandler);
                // 修改属性值
                memberValues.put("value", "123");
                memberValues.put("names", new String[] {"Answer", "AI", "Jaemon"});
                System.out.println();
            }

            for (Method declaredMethod : Pairs.class.getDeclaredMethods()) {
                if (declaredMethod.isAnnotationPresent(MyProperties.class)) {
                    MyProperties myProperties = declaredMethod.getAnnotation(MyProperties.class);
                    InvocationHandler invocationHandler = Proxy.getInvocationHandler(myProperties);
                    Field values = invocationHandler.getClass().getDeclaredField("memberValues");
                    values.setAccessible(true);
                    Map<String, Object> memberValues =(Map<String, Object>) values.get(invocationHandler);
                    memberValues.put("value", "123");
                    System.out.println();
                }

            }
        } catch (Exception e) {
            e.printStackTrace();
        }

        System.out.println("修改后");
        for (Field field : Pairs.class.getDeclaredFields()) {
            MyProperties myProperties = field.getAnnotation(MyProperties.class);
            System.out.println(myProperties.value());
            System.out.println(Arrays.asList(myProperties.names()));
            System.out.println();
        }

    }

}

运行结果

修改前
Jaemon
[]

Answer
[Answer, AI]




修改后
123
[Answer, AI, Jaemon]

123
[Answer, AI, Jaemon]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Jaemon

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值