之前一直用的Apache的包,自己也写过不少关于java方法反射的工具类.很多都是一写就丢了.得不到复用.
现将工具整合一下,以供后用.在这里记录一下过程.以便后来忘记某些"特殊"点 :).
基于java本身,故反射从class开始.由于知识的局限性,可能分析的有点片面.希望看到这片文章的人能提点一下.不胜感激 :).
对反射Method的小结:
getDeclaredMethods 该方法只能得到反射类本身的公开(public)的,保护(protected)的,私有(private)的方法.得不到超类的方法.
getDeclaredMethod 该方法只能得到反射类本身的公开的,保护的,私有的方法.得不到超类的方法.
getMethods 该方法只能得到公开(public)的方法,包括类本身以及他的超类.并且返回的肯定是最后复写的方法
getMethod 该方法只能得到公开(public)的方法,包括类本身以及他的超类.并且返回的肯定是最后复写的方法
返回的方法即时的拷贝,抛处异常只是因为返回了null对象而已 --> class本身保留了一个(native)getDeclaredMethods0的方法,该方法是以上方法的包装.由于class内部维护了对method的缓存,在不重新加载该类的情况下,该缓存一直生效.在第一次调用反射method方法时建立缓存.
看了一下getDeclaredMethod跟getMethod的实现,都是先去调用getDeclaredMethods/getMethods的实现,然后遍历匹配,匹配到就返回.
private static Method searchMethods(Method[] methods, String name,
Class<?>[] parameterTypes) {
Method res = null;
String internedName = name.intern();
for (int i = 0; i < methods.length; i++) {
Method m = methods[i];
if (m.getName() == internedName
&& arrayContentsEq(parameterTypes, m.getParameterTypes())
&& (res == null || res.getReturnType().isAssignableFrom(
m.getReturnType())))
res = m;
}
return (res == null ? res : getReflectionFactory().copyMethod(res));
}
可以看到,先匹配方法名,再匹配参数类型,最后还匹配返回类型(记得在一个类中方法名+参数必须唯一来着,匹配返回值有什么特殊用意么?
所以等会写工具类的时候,可以考虑以类名+方法名+参数类型[+返回类型]来构造一个进程级的方法缓存.以class反射方法一样的手段 :)
PS:其实method本身的toString()方法已经构造了一个很好的key了
关于Method本身的属性:
在继承class本身的情况下,还多了参数类型,参数的注解类型,返回值类型等等一些在写一个method的时候可以写入的元素.(反射不就是反射这些本身写进去的元素么 :)
关于method的小结就到这里了,这些东西足够写一个methodUtil了.
开始动手~