Java Method类

Method类位于java.lang.reflect包下,在Java反射中Method类描述的是类的方法信息(包括:方法修饰符、方法名称、参数列表等等)。

定义

public final class Method extends AbstractMethod implements GenericDeclaration, Member

在 JDK 中 java.lang.reflect.Method 和 java.lang.reflect.Constructor 都继承自 Executable,因此它俩也有同样的能力。

获取Method类对象

一共有4种方法,全部都在Class类中:

1. getMethods(): 获得类的public类型的方法

2. getMethod(String name, Class[] params): 获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型

3. getDeclaredMethods(): 获取类中所有的方法(public、protected、default、private)

4. getDeclaredMethod(String name, Class[] params): 获得类的特定方法,name参数指定方法的名字,params参数指定方法的参数类型

常用方法

public static void main(String[] args) throws Exception {
    //使用反射第一步:获取操作类MethodDemoFieldDemo所对应的Class对象
    Class < ?>cls = Class.forName("com.testReflect.MethodDemo");
    //使用MethodDemo类的class对象生成 实例
    Object obj = cls.newInstance();

    //获取public int addResult(int addNum)方法
    Method addMethod = cls.getMethod("addResult", new Class[] {
        int.class
    });
    System.out.println("修饰符: " + Modifier.toString(addMethod.getModifiers()));
    System.out.println("返回值: " + addMethod.getReturnType());
    System.out.println("方法名称: " + addMethod.getName());
    System.out.println("参数列表: " + addMethod.getParameterTypes());
    int result = (int) addMethod.invoke(obj, 2);
    System.out.println("调用addResult后的运行结果:" + result);

    System.out.println("--------------------------------");

    //获取public String toString() 方法
    Method toStringMethod = cls.getMethod("toString", new Class[] {});
    System.out.println("修饰符: " + Modifier.toString(toStringMethod.getModifiers()));
    System.out.println("返回值: " + toStringMethod.getReturnType());
    System.out.println("方法名称: " + toStringMethod.getName());
    System.out.println("参数列表: " + toStringMethod.getParameterTypes());
    String msg = (String) toStringMethod.invoke(obj);
    System.out.println("调用toString后的运行结果:" + msg);
}

Method.invoke()反射调用方法

/** 
 * <p>java反射中Method类invoke方法的用法</p> * 
 */
public class InvokeTester {
    private String name;

    public void setName(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }

    public InvokeTester() {}

    public int add(int param1, int param2) {
        return param1 + param2;
    }
    public String echo(String mesg) {
        return "echo" + mesg;
    }

    public static void main(String[] args) {
        Class classType = InvokeTester.class;
        try {
            Object invokertester = classType.newInstance(); //1  
            Method addMethod = classType.getMethod("add", new Class[] { //2  
                int.class,
                int.class
            });

            Object result = addMethod.invoke(invokertester, new Object[] { //3  
                new Integer(100),
                new Integer(200)
            });

            System.out.println(result); 
            Method echo = classType.getMethod("echo", new Class[] {
                String.class
            });
            Object obj = echo.invoke(invokertester, new Object[] {
                new String("jy is very good!!!")
            });
            System.out.println(obj.toString());

            ////////////////////  
            InvokeTester test = new InvokeTester(); //1  
            test.setName("黄翊"); //2  
            //Method[] methods;  
            Method[] methods = test.getClass().getDeclaredMethods(); //3  
            //循环查找获取id方法,并执行查看是否有返回值  
            for (int i = 0; i < methods.length; i++) {
                //如果此方法有get和Id关键字则执行  
                if (methods[i].getName().indexOf("get") != -1 && methods[i].getName().indexOf("Name") != -1) {
                    try {
                        // 获取此get方法返回值,判断是否有值,如果没有值说明即将执行的操作新增  
                        if (methods[i].invoke(test, null) == null) { //4                                             
                            System.out.println("此对象没有值!!!");
                        } else {
                            Object strName = methods[i].invoke(test, null);
                            System.out.println(strName);
                        }
                    } catch(Exception e) {
                        System.out.print("");
                    }
                }
            }
        } catch(IllegalAccessException ex) {} catch(InstantiationException ex) {} catch(SecurityException ex) {} catch(NoSuchMethodException ex) {} catch(InvocationTargetException ex) {} catch(IllegalArgumentException ex) {}
    }
}

Method类的invoke(Object obj,Object args[])方法接收的参数必须为对象,如果参数为基本类型数据,必须转换为相应的包装类型的对象。invoke()方法的返回值总是对象,如果实际被调用的方法的返回类型是基本类型数据,那么invoke()方法会把它转换为相应的包装类型的对象,再将其返回.

例子

public class MethodTypeSpy extends BaseTestClass {
    private static final String fmt = "%24s:   %s\n";
    private static final String HELLO_WORLD = "I'm cute shixin";
    @Deprecated
    public static void main(String[] args) throws ClassNotFoundException {
        MethodTypeSpy methodTypeSpy = new MethodTypeSpy();
        Class<? extends MethodTypeSpy> cls = methodTypeSpy.getClass();
        printFormat("Class:%s \n", cls.getCanonicalName());
        Method[] declaredMethods = cls.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            printFormat(fmt, "Method name", declaredMethod.getName());  //获得单独的方法名
            //获得完整的方法信息(包括修饰符、返回值、路径、名称、参数、抛出值)
            printFormat(fmt, "toGenericString", declaredMethod.toGenericString());

            int modifiers = declaredMethod.getModifiers();      //获得修饰符
            printFormat(fmt, "Modifiers", Modifier.toString(modifiers));

            System.out.format(fmt, "ReturnType", declaredMethod.getReturnType());   //获得返回值
            System.out.format(fmt, "getGenericReturnType", declaredMethod.getGenericReturnType());//获得完整信息的返回值

            Class<?>[] parameterTypes = declaredMethod.getParameterTypes(); //获得参数类型
            Type[] genericParameterTypes = declaredMethod.getGenericParameterTypes();
            for (int i = 0; i < parameterTypes.length; i++) {
                System.out.format(fmt, "ParameterType", parameterTypes[i]);
                System.out.format(fmt, "GenericParameterType", genericParameterTypes[i]);
            }

            Class<?>[] exceptionTypes = declaredMethod.getExceptionTypes();     //获得异常名称
            Type[] genericExceptionTypes = declaredMethod.getGenericExceptionTypes();
            for (int i = 0; i < exceptionTypes.length; i++) {
                System.out.format(fmt, "ExceptionTypes", exceptionTypes[i]);
                System.out.format(fmt, "GenericExceptionTypes", genericExceptionTypes[i]);
            }

            Annotation[] annotations = declaredMethod.getAnnotations(); //获得注解
            for (Annotation annotation : annotations) {
                System.out.format(fmt, "Annotation", annotation);
                System.out.format(fmt, "AnnotationType", annotation.annotationType());
            }
        }
    }
}

运行结果:

Class:net.sxkeji.shixinandroiddemo2.test.reflection.MethodTypeSpy 
             Method name:   main
         toGenericString:   public static void net.sxkeji.shixinandroiddemo2.test.reflection.MethodTypeSpy.main(java.lang.String[]) throws java.lang.ClassNotFoundException
               Modifiers:   public static
              ReturnType:   void
    getGenericReturnType:   void
           ParameterType:   class [Ljava.lang.String;
    GenericParameterType:   class [Ljava.lang.String;
          ExceptionTypes:   class java.lang.ClassNotFoundException
   GenericExceptionTypes:   class java.lang.ClassNotFoundException
              Annotation:   @java.lang.Deprecated()
          AnnotationType:   interface java.lang.Deprecated

Process finished with exit code 0

权限总结

1. public的static的方法:没有任何权限问题,getMethod()就可以满足,根本不用getDeclaredMethod出马,更不用setAccessiable(true)

2. public的非静态的方法:没有任何权限问题,getMethod()就可以满足,根本不用getDeclaredMethod出马,更不用setAccessiable(true),但是,在invoke时,第一个参数必须是具体的某一个对象,static的可要可不要

3. protected的非静态方法:必须使用getDeclaredMethod,不能使用getMethod,不用设置setAccessiable(true)

4. friendly的非静态方法:必须使用getDeclaredMethod,不能使用getMethod,不用设置setAccessiable(true)

5. private的非静态方法:必须使用getDeclaredMethod,不能使用getMethod,必须设置setAccessiable(true)

版权声明:本文为JAVASCHOOL原创文章,未经本站允许不得转载。