- 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]