`

java.lang.reflect.Method

阅读更多
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;
    }
}

 

分享到:
评论

相关推荐

    server frame base on c.rar

    java.lang.NullPointerException ... at java.lang.reflect.Method.invoke(Method.java:498) at org.apache.tomcat.websocket.pojo.PojoMessageHandlerWholeBase.onMessage(PojoMessageHandlerWholeBase.java:80)

    javassist3.19GA.jar

    用以执行和JDK反射API中java.lang.Class,,java.lang.reflect.Method,, java.lang.reflect.Method .Field相同的操作。这些类可以使你在目标类被加载前,轻松的获得它的结构,函数,以及属性。此外,不仅仅是在功能...

    ExcelExportUtils.java

    import java.lang.reflect.Method; import java.text.SimpleDateFormat; import java.util.Date; import java.util.List; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.hssf.util....

    java Reflection 反射机制 反编译

    import java.lang.reflect.Method; import java.lang.reflect.Modifier; public class ReflectionTest { public static void main(String[] args) { Class c = null; try { c = Class.forName("java.lang....

    android 奔溃日志收集 发送邮件到邮箱

    集成邮件工具类,用于发送某个应用的奔溃日志信息到邮箱。...at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:10

    jaxen.jar和dom4j.jar

    at java.lang.reflect.Method.invoke(Unknown Source) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable.run...

    java 反射例子 代码

    java.lang.reflect.Constructor; java.lang.reflect.Field; java.lang.reflect.Method; java.lang.reflect.Modifier;

    aop面向切面需要的jar包

    Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWorldException at java.net.URLClassLoader$1.run(URLClassLoader.java:200) at java.security.Access...

    org.eclipse.jdt.core_3.5.2.v_981_R35x

    at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44) at org.junit.internal.runners.model.ReflectiveCallable....

    Java高级程序设计实战教程第三章-Java反射机制.pptx

    //类的成员变量 java.lang.reflect.Method;//类的方法 java.lang.reflect.Modifier;//访问权限 Java高级程序设计实战教程第三章-Java反射机制全文共15页,当前为第6页。 3.2.4 使用反射机制的步骤 导入Jjava.lang....

    Java 高级特性.doc

    import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.util.Collection; import java.util.Vector; public class ProxyTest { public ...

    信息: Deploying web application directory lx01

    at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:289) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:414) 2010-11-11 ...

    COS——R.log

    at java.lang.reflect.Method.invoke(Method.java:585) at org.apache.axis.providers.java.RPCProvider.invokeMethod(RPCProvider.java:397) at org.apache.axis.providers.java.RPCProvider.processMessage...

    java反射机制

    import java.lang.reflect.Method; public class DumpMethods { public static void main(String args[]) throws Exception { // 加载并初始化命令行参数指定的类 Class&lt;?&gt; classType = Class.forName(args[0])...

    c3p0工具包(jdbc)

    import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import javax.servlet.Filter; import javax.servlet.FilterChain; import javax.servlet....

    数据库工具类DatabaseUtil.java

    java.lang.reflect.Method method = clazz.getMethod("close", null); method.invoke(resource, null); } catch (Exception e) { // e.printStackTrace(); } } /** * 执行 SELECT 等 SQL 语句并返回结果集. ...

    java业务层框架开发ibatis(java源码)

    import java.lang.reflect.Method; import java.sql.CallableStatement; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.PreparedStatement; import java.sql.SQLException; ...

    HIbernate4.3.6整合c3p0所需jar

    at java.lang.reflect.Method.invoke(Method.java:597) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:45) at org.junit.internal.runners.model.ReflectiveCallable....

    Spring原理模拟代码

    import java.lang.reflect.Method; import java.util.HashMap; import java.util.List; import java.util.Map; import org.jdom.Document; import org.jdom.Element; import org.jdom.input.SAXBuilder; public ...

    struts2驱动包

    at java.lang.reflect.Method.invoke(Method.java:597) at org.apache.catalina.startup.Bootstrap.start(Bootstrap.java:288) at org.apache.catalina.startup.Bootstrap.main(Bootstrap.java:413) Caused by: java...

Global site tag (gtag.js) - Google Analytics