代码片段:
Method[] method = Pow3.class.getDeclaredMethods();
method[0].invoke(new Pow3(), 1);
此段代码通过反射获取类所定义的方法,具体流程是:通过class 的 getDeclaredMethods 方法获取类的定义的方法,
@CallerSensitive
public Method[] getDeclaredMethods() throws SecurityException {
// be very careful not to change the stack depth of this
// checkMemberAccess call for security reasons
// see java.lang.SecurityManager.checkMemberAccess
checkMemberAccess(Member.DECLARED, Reflection.getCallerClass(), true);
return copyMethods(privateGetDeclaredMethods(false));
}
主要逻辑在privateGetDeclaredMethods方法和copyMethods 方法中现在咱们来一个个分析该方法
private Method[] privateGetDeclaredMethods(boolean publicOnly) {
checkInitted();
Method[] res;
//获取反射属性的列表
ReflectionData<T> rd = reflectionData();
if (rd != null) {
res = publicOnly ? rd.declaredPublicMethods : rd.declaredMethods;
if (res != null) return res;
}
// No cached value available; request value from VM
res = Reflection.filterMethods(this, getDeclaredMethods0(publicOnly));
if (rd != null) {
if (publicOnly) {
rd.declaredPublicMethods = res;
} else {
rd.declaredMethods = res;
}
}
return res;
}
此方法中有个ReflectionData 数据结构,是存放反射的类相关的方法,属性信息
static class ReflectionData<T> {
volatile Field[] declaredFields;
volatile Field[] publicFields;
volatile Method[] declaredMethods;
volatile Method[] publicMethods;
volatile Constructor<T>[] declaredConstructors;
volatile Constructor<T>[] publicConstructors;
// Intermediate results for getFields and getMethods
volatile Field[] declaredPublicFields;
volatile Method[] declaredPublicMethods;
// Value of classRedefinedCount when we created this ReflectionData instance
final int redefinedCount;
ReflectionData(int redefinedCount) {
this.redefinedCount = redefinedCount;
}
}
//获取反射属性的列表
ReflectionData<T> rd = reflectionData();
// Lazily create and cache ReflectionData
private ReflectionData<T> reflectionData() {
//先从缓存中取 并放到软引用中,这样有利于在内存不足的情况下jvm 回收
SoftReference<ReflectionData<T>> reflectionData = this.reflectionData;
int classRedefinedCount = this.classRedefinedCount;
ReflectionData<T> rd;
if (useCaches &&
reflectionData != null &&
(rd = reflectionData.get()) != null &&
rd.redefinedCount == classRedefinedCount) {
return rd;
}
// else no SoftReference or cleared SoftReference or stale ReflectionData
// -> 如果缓存中没有从VM里面拿
return newReflectionData(reflectionData, classRedefinedCount);
}
private ReflectionData<T> newReflectionData(SoftReference<ReflectionData<T>> oldReflectionData,
int classRedefinedCount) {
if (!useCaches) return null;
while (true) {
ReflectionData<T> rd = new ReflectionData<>(classRedefinedCount);
// 通过cas 算法,从vm 中拿取数据
if (Atomic.casReflectionData(this, oldReflectionData, new SoftReference<>(rd))) {
return rd;
}
// else retry
oldReflectionData = this.reflectionData;
classRedefinedCount = this.classRedefinedCount;
if (oldReflectionData != null &&
(rd = oldReflectionData.get()) != null &&
rd.redefinedCount == classRedefinedCount) {
return rd;
}
}
}
这个是读取反射对象的大概过程,接下来分析copyMethods
private static Method[] copyMethods(Method[] arg) {
Method[] out = new Method[arg.length];
ReflectionFactory fact = getReflectionFactory();
for (int i = 0; i < arg.length; i++) {
out[i] = fact.copyMethod(arg[i]);
}
return out;
}
fact.copyMethod 方法最终调用的是method 的copy 所以说。通过反射获取method 每次都是生成一个对象的拷贝,是一个新的method 对象,
Method copy() {
// This routine enables sharing of MethodAccessor objects
// among Method objects which refer to the same underlying
// method in the VM. (All of this contortion is only necessary
// because of the "accessibility" bit in AccessibleObject,
// which implicitly requires that new java.lang.reflect
// objects be fabricated for each reflective call on Class
// objects.)
Method res = new Method(clazz, name, parameterTypes, returnType,
exceptionTypes, modifiers, slot, signature,
annotations, parameterAnnotations, annotationDefault);
res.root = this;
// Might as well eagerly propagate this if already present
res.methodAccessor = methodAccessor;
return res;
}
其实对method 的方法调用最终是methodAccessor的invoke 调用 ,也是委托给MethodAccessorImpl 的invoke 调用
public Object invoke(Object paramObject, Object[] paramArrayOfObject)
throws IllegalArgumentException, InvocationTargetException
{
return this.delegate.invoke(paramObject, paramArrayOfObject);
}
再委托给NativeMethodAccessorImpl 的invoke 方法
public Object invoke(Object paramObject, Object[] paramArrayOfObject)
throws IllegalArgumentException, InvocationTargetException
{
if (++this.numInvocations > ReflectionFactory.inflationThreshold()) {
MethodAccessorImpl localMethodAccessorImpl = (MethodAccessorImpl)new MethodAccessorGenerator().generateMethod(this.method.getDeclaringClass(), this.method.getName(), this.method.getParameterTypes(), this.method.getReturnType(), this.method.getExceptionTypes(), this.method.getModifiers());
this.parent.setDelegate(localMethodAccessorImpl);
}
return invoke0(this.method, paramObject, paramArrayOfObject);
}
此段逻辑是当判断 numInvocations>15次调用会生成MethodAccessorImplXXX字节码,如果小于15次就直接调用原生的private static native Object invoke0(Method paramMethod, Object paramObject, Object[] paramArrayOfObject) 方法进行方法的调用。 需要注意的是,由于numInvocations 不是线程安全的。所以在高并发的情况下。会生成很多无用的类。如果并发1000个,会有999个是无用的,会增加perm 区满,导致永久区溢出,