package java.lang.reflect; import sun.reflect.MethodAccessor; import sun.reflect.Reflection; /** * * 描述方法的类 * * 注意使用反射的方式是首先通过 * Class.getMethod(String name, Class[] parameterTypes)获得一个Method对象 * String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得 * Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Object obj, Object[] args) * 这里obj指调用方法的对象,args表示每个参数对应的值 * * 例子,一下两种方式的效果是一样的(当然性能不同) * String ost = "lqtest"; * String nst = ost.substring(2,6); * * String ost2 = "lqtest"; * Class[] types = {int.class, int.class}; * Method med = String.class.getMethod("substring", types); * Object[] values ={new Integer(2), new Integer(6)}; * String nst2 = (String) med.invoke(ost2, values); * * 使用反射一切都是变化的,类名,方法名,参数列表,都是变量,而不是写死的,他们 * 在运行时才知道具体值,而不是编译期 * * comment by liqiang * * @author Kenneth Russell * @author Nakul Saraiya */ public final class Method extends AccessibleObject implements Member { //定义此方法的类对象 private Class clazz; private int slot; //方法名,从1.4开始它变成intern的形式 private String name; //返回类型 private Class returnType; //参数列表 private Class[] parameterTypes; //异常列表 private Class[] exceptionTypes; //方法的描述符 private int modifiers; //处理方法的实际对象 private volatile MethodAccessor methodAccessor; //如果当前对象是通过拷贝得到的,则root指向拷贝前的对象 private Method root; //调用对象的安全检查的缓存,保存上一个通过检查的调用对象,如果当前的调用对象 //不是上一个调用对象则做安全检查 private volatile Class securityCheckTargetClassCache; //构造函数 Method(Class declaringClass, String name, Class[] parameterTypes, Class returnType, Class[] checkedExceptions, int modifiers, int slot) { this.clazz = declaringClass; this.name = name; this.parameterTypes = parameterTypes; this.returnType = returnType; this.exceptionTypes = checkedExceptions; this.modifiers = modifiers; this.slot = slot; } //通过本对象的数据生成一个新对象 Method copy() { //通过本对象的数据生成一个新对象 Method res = new Method(clazz, name, parameterTypes, returnType, exceptionTypes, modifiers, slot); //新对象的root指向原对象 res.root = this; //新对象与原对象公用一个MethodAccessor res.methodAccessor = methodAccessor; return res; } //返回声明此函数的类 public Class getDeclaringClass() { return clazz; } //返回方法名 public String getName() { return name; } //返回描述符 public int getModifiers() { return modifiers; } //取得返回类型 public Class getReturnType() { return returnType; } //返回参数列表 public Class[] getParameterTypes() { return copy(parameterTypes); } //返回异常列表 public Class[] getExceptionTypes() { return copy(exceptionTypes); } //判断obj是否与当前方法对象相等 public boolean equals(Object obj) { if (obj != null && obj instanceof Method) {//如果是方法对象 //转型 Method other = (Method)obj; //定义此方法的类和方法名相等 if ((getDeclaringClass() == other.getDeclaringClass()) && (getName() == other.getName())) { /* Avoid unnecessary cloning */ Class[] params1 = parameterTypes; Class[] params2 = other.parameterTypes; //比较参数列表 if (params1.length == params2.length) { for (int i = 0; i < params1.length; i++) { if (params1[i] != params2[i]) return false; } return true; } } } return false; } //返回hashCode public int hashCode() { return getDeclaringClass().getName().hashCode() ^ getName().hashCode(); } //方法对象的字符串表示 public String toString() { try { StringBuffer sb = new StringBuffer(); int mod = getModifiers(); if (mod != 0) { //标志符 sb.append(Modifier.toString(mod) + " "); } //注意它这里用的是Field方法中显示类的名字,这个方法显示数组类型跟Class.getName()不同 //添加返回类型 sb.append(Field.getTypeName(getReturnType()) + " "); //添加类名 sb.append(Field.getTypeName(getDeclaringClass()) + "."); //添加方法名 sb.append(getName() + "("); //参数列表 Class[] params = parameterTypes; // avoid clone for (int j = 0; j < params.length; j++) { sb.append(Field.getTypeName(params[j])); if (j < (params.length - 1)) sb.append(","); } sb.append(")"); //异常列表 Class[] exceptions = exceptionTypes; // avoid clone if (exceptions.length > 0) { sb.append(" throws "); for (int k = 0; k < exceptions.length; k++) { sb.append(exceptions[k].getName()); if (k < (exceptions.length - 1)) sb.append(","); } } return sb.toString(); } catch (Exception e) { return "<" + e + ">"; } } /** * * 注意使用反射的方式是首先通过 * Class.getMethod(String name, Class[] parameterTypes)获得一个Method对象 * String表示方法名,parameterTypes表示参数列表中的每个参数对应的类型,这时先获得 * Class对象中Method对象,与实际的操作对象无关,然后调用此方法,是通过Method.(Object obj, Object[] args) * 如果调用的方法是static的则obj对象为null,如果方法没有参数,则args的长度为0或为null * 如果返回值是原始类型则返回它的封装类,如果返回值是void则返回null */ public Object invoke(Object obj, Object[] args) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException { if (!override) { if (!Reflection.quickCheckMemberAccess(clazz, modifiers)) { //获得调用对象的Class对象 Class caller = Reflection.getCallerClass(1); Class targetClass = ((obj == null || !Modifier.isProtected(modifiers)) ? clazz : obj.getClass()); //调用此操作的对象或方法调用作用的对象与缓存不同,则做安全检查 if (securityCheckCache != caller || targetClass != securityCheckTargetClassCache) { Reflection.ensureMemberAccess(caller, clazz, obj, modifiers); securityCheckCache = caller; //通过安全检查的调用对象,缓存它供下次调用时使用 securityCheckTargetClassCache = targetClass; } } } if (methodAccessor == null) acquireMethodAccessor(); return methodAccessor.invoke(obj, args); } //如果此对象是由copy生成的,则对象与生成此对象的对象使用同一个MethodAccessor private void acquireMethodAccessor() { MethodAccessor tmp = null; if (root != null) tmp = root.getMethodAccessor(); if (tmp != null) { methodAccessor = tmp; return; } //不是由copy得来创建MethodAccessor对象 tmp = reflectionFactory.newMethodAccessor(this); setMethodAccessor(tmp); } //返回MethodAccessor对象 MethodAccessor getMethodAccessor() { return methodAccessor; } //设置MethodAccessor对象 void setMethodAccessor(MethodAccessor accessor) { methodAccessor = accessor; if (root != null) {//如果此对象是由copy的来 //递归调用其上级 root.setMethodAccessor(accessor); } } //生成一个新的Class数组并将原数组内容考到新数组中 static Class[] copy(Class[] in) { int l = in.length; if (l == 0) return in; Class[] out = new Class[l]; for (int i = 0; i < l; i++) out[i] = in[i]; return out; } }