前提介绍:
java获取方法有两种方式:
1、class.getMethods
2、class.getDeclaredMethod
查看JDK注释,这两个方法:
getMethods:返回一个数组,其中包含反映该类对象表示的类或接口的所有公共方法的方法对象,包括由类或接口声明的方法对象以及从超类和超接口继承的方法对象。
getDeclaredMethod:返回一个方法对象,该对象反映由该类对象表示的类或接口的指定声明方法。
那方法上面的注解数据是挂在哪的呢?
private synchronized Map<Class<? extends Annotation>, Annotation> declaredAnnotations() {
if (declaredAnnotations == null) {
Executable root = getRoot();
if (root != null) {
declaredAnnotations = root.declaredAnnotations();
} else {
declaredAnnotations = AnnotationParser.parseAnnotations(
getAnnotationBytes(),
sun.misc.SharedSecrets.getJavaLangAccess().
getConstantPool(getDeclaringClass()),
getDeclaringClass());
}
}
return declaredAnnotations;
}
//
private Method root;
//
Executable getRoot() {
return root;
}
方法上面的注解数据是放在root的declaredAnnotations数组里面的
正文内容:
getMethods获取的methods和getDeclaredMethod获取的methods的root是不同的两个实例。意味着,方法上面的注解实例存在两个。
so,如果不确定方法上面的注解使用时是从哪里获取(getMethods or getDeclaredMethod)的,哪你两个方法上面的注解实例都要反射修改。
上个例子:
@SneakyThrows
public void changeAnnotation() {
Method method_4_getMethods = this.getClass().getMethod("annotation");
Options options_4_getMethods = method_4_getMethods.getAnnotationsByType(Options.class)[0];
System.out.println(String.format("getMethods修改前:%d", options_4_getMethods.timeout()));
changeTimeout(options_4_getMethods, 8888);
System.out.println(String.format("getMethods修改后:%d", options_4_getMethods.timeout()));
Method method_4_getDeclaredMethod = this.getClass().getDeclaredMethod("annotation");
Options options_4_getDeclaredMethod = method_4_getDeclaredMethod.getAnnotationsByType(Options.class)[0];
System.out.println(String.format("getDeclaredMethod修改前:%d", options_4_getDeclaredMethod.timeout()));
changeTimeout(options_4_getDeclaredMethod, 9999);
System.out.println(String.format("getDeclaredMethod修改前:%d", options_4_getDeclaredMethod.timeout()));
}
@SneakyThrows
private void changeTimeout(Options options, int timeout) {
InvocationHandler invocationHandler = Proxy.getInvocationHandler(options);
Field memberValues = invocationHandler.getClass().getDeclaredField("memberValues");
memberValues.setAccessible(true);
Map memberValuesMap = (Map) memberValues.get(invocationHandler);
memberValuesMap.put("timeout", timeout);
}
@Options(timeout = -1)
public void annotation() {
}
结果输出
getMethods修改前:-1
getMethods修改后:8888
getDeclaredMethod修改前:-1
getDeclaredMethod修改前:9999
debug:
1、root是两个实例
2、注解是两个实例
到此这篇关于Java方法上注解值修改不成功的文章就介绍到这了,更多相关java方法上注解内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!