java中方法的反射调用示例

Mothod类的基本介绍

要动态获取一个对象方法的信息,首先需要通过下列方法之一创建一个 Method 类型的对象或者数组。

getMethods()
getMethods(String name,Class<?> …parameterTypes)
getDeclaredMethods()
getDeclaredMethods(String name,Class<?>...parameterTypes)

如果是访问指定的构造方法,需要根据该方法的入口参数的类型来访问。例如,访问一个名称为 max,入口参数类型依次为 int 和 String 类型的方法。

下面的两种方式均可以实现:

objectClass.getDeclaredConstructor("max",int.class,String.class);
objectClass.getDeclaredConstructor("max",new Class[]{int.class,String.class});
静态方法名称说明
getName()获取该方法的名称
getParameterType()按照声明顺序以 Class 数组的形式返回该方法各个参数的类型
getReturnType()以 Class 对象的形式获得该方法的返回值类型
getExceptionTypes()以 Class 数组的形式获得该方法可能抛出的异常类型
invoke(Object obj,Object…args)利用 args 参数执行指定对象 obj 中的该方法,返回值为 Object 类型
isVarArgs()查看该方法是否允许带有可变数量的参数,如果允许返回 true,否则返回 false
getModifiers()获得可以解析出该方法所采用修饰符的整数

示例

方法的代码示例

下面通过一个案例来演示如何调用 Method 类的方法获取动态类中方法的信息。

1)首先创建一个 Book1 类,并编写 4 个具有不同作用域的方法。Book1 类的最终代码如下:

public class Book1 {
    // static 作用域方法
    static void staticMethod() {
        System.out.println("执行staticMethod()方法");
    }
    // public 作用域方法
    public int publicMethod(int i) {
        System.out.println("执行publicMethod()方法");
        return 100 + i;
    }
    // protected 作用域方法
    protected int protectedMethod(String s, int i) throws NumberFormatException {
        System.out.println("执行protectedMethod()方法");
        return Integer.valueOf(s) + i;
    }
    // private 作用域方法
    private String privateMethod(String... strings) {
        System.out.println("执行privateMethod()方法");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < sb.length(); i++) {
            sb.append(strings[i]);
        }
        return sb.toString();
    }
}

反射调用方法的代码示例

2)编写测试类 Test02,在该类的 main() 方法中通过反射访问 Book1 类中的所有方法,并将该方法是否带可变类型参数、入口参数类型和可能拋出的异常类型信息输出到控制台。

Test02 类的代码如下:

public class Test02 {
    public static void main(String[] args) {
        // 获取动态类Book1
        Book1 book = new Book1();
        Class class1 = book.getClass();
        // 获取Book1类的所有方法
        Method[] declaredMethods = class1.getDeclaredMethods();
        for (int i = 0; i < declaredMethods.length; i++) {
            Method method = declaredMethods[i];
            System.out.println("方法名称为:" + method.getName());
            System.out.println("方法是否带有可变数量的参数:" + method.isVarArgs());
            System.out.println("方法的参数类型依次为:");
            // 获取所有参数类型
            Class[] methodType = method.getParameterTypes();
            for (int j = 0; j < methodType.length; j++) {
                System.out.println(" " + methodType[j]);
            }
            // 获取返回值类型
            System.out.println("方法的返回值类型为:" + method.getReturnType());
            System.out.println("方法可能抛出的异常类型有:");
            // 获取所有可能抛出的异常
            Class[] methodExceptions = method.getExceptionTypes();
            for (int j = 0; j < methodExceptions.length; j++) {
                System.out.println(" " + methodExceptions[j]);
            }
            boolean isTurn = true;
            while (isTurn) {
                try { // 如果该成员变量的访问权限为private,则抛出异常
                    isTurn = false;
                    if (method.getName().equals("staticMethod")) { // 调用没有参数的方法
                        method.invoke(book);
                    } else if (method.getName().equals("publicMethod")) { // 调用一个参数的方法
                        System.out.println("publicMethod(10)的返回值为:" + method.invoke(book, 10));
                    } else if (method.getName().equals("protectedMethod")) { // 调用两个参数的方法
                        System.out.println("protectedMethod(\"10\",15)的返回值为:" + method.invoke(book, "10", 15));
                    } else if (method.getName().equals("privateMethod")) { // 调用可变数量参数的方法
                        Object[] parameters = new Object[] { new String[] { "J", "A", "V", "A" } };
                        System.out.println("privateMethod()的返回值为:" + method.invoke(book, parameters));
                    }
                } catch (Exception e) {
                    System.out.println("在设置成员变量值时抛出异常,下面执行setAccessible()方法");
                    method.setAccessible(true); // 设置为允许访问private方法
                    isTurn = true;
                }
            }
            System.out.println("=============================\n");
        }
    }
}

示例运行结果

3)运行测试类 test02,程序将会依次动态访问 Book1 类中的所有方法。访问 staticMethod() 方法的运行效果如下所示:

方法名称为:staticMethod
方法是否带有可变数量的参数:false
方法的参数类型依次为:
方法的返回值类型为:void
方法可能抛出的异常类型有:

执行staticMethod()方法

访问 publicMethod() 方法的运行效果如下所示:
方法名称为:publicMethod
方法是否带有可变数量的参数:false
方法的参数类型依次为:
int
方法的返回值类型为:int
方法可能抛出的异常类型有:
执行publicMethod()方法
publicMethod(10)的返回值为:110

访问 protectedMethod() 方法的运行效果如下所示:

方法名称为:protectedMethod
方法是否带有可变数量的参数:false
方法的参数类型依次为:
class java.lang.String
int
方法的返回值类型为:int
方法可能抛出的异常类型有:
class java.lang.NumberFormatException
执行protectedMethod()方法
protectedMethod("10",15)的返回值为:25

访问 privateMethod() 方法的运行效果如下所示:

方法名称为:privateMethod
方法是否带有可变数量的参数:true
方法的参数类型依次为:
class java.lang.String;
方法的返回值类型为:class java.lang.String
方法可能抛出的异常类型有:
在设置成员变量值时抛出异常,下面执行setAccessible()方法
执行privateMethod()方法
privateMethod()的返回值为:
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java,可以使用反射机制来调用方法。通过反射,可以在运行时获取类的信息,并动态地调用类的方法。 要调用某个方法,首先需要获取对应的Method对象。可以使用Class类的getMethod()方法或getDeclaredMethod()方法来获取Method对象。getMethod()方法只能获取公共方法,而getDeclaredMethod()方法可以获取所有方法,包括私有方法。获取Method对象后,就可以使用invoke()方法调用方法。 下面是一个示例代码,演示了如何使用反射调用方法: ```java import java.lang.reflect.Method; public class ReflectExample { public static void main(String[] args) throws Exception { // 获取Class对象 Class<?> clazz = MyClass.class; // 获取方法名和参数类型 String methodName = "myMethod"; Class<?>[] parameterTypes = {int.class, String.class}; // 获取Method对象 Method method = clazz.getDeclaredMethod(methodName, parameterTypes); method.setAccessible(true); // 如果方法是私有的,需要设置可访问 // 创建对象实例 Object obj = clazz.newInstance(); // 调用方法 Object result = method.invoke(obj, 123, "hello"); // 输出结果 System.out.println(result); } } class MyClass { private String myMethod(int num, String str) { return str + num; } } ``` 以上代码,首先通过Class.forName()方法获取MyClass类的Class对象。然后,使用getDeclaredMethod()方法获取方法名为"myMethod",参数类型为int和String的Method对象。接着,使用newInstance()方法创建MyClass类的实例。最后,调用invoke()方法调用方法,并获取返回值。 我希望我的回答对你有帮助。如果你还有其他
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值