Java反射调用方法案例如何用

wen java案例 18

本文目录导读:

Java反射调用方法案例如何用

  1. 基本案例:调用无参方法
  2. 带参数的方法调用
  3. 静态方法调用
  4. 处理异常的方法调用
  5. 实际应用:动态调用任意对象的方法
  6. 批量执行测试方法
  7. 关键要点

我来给你展示几个Java反射调用方法的实际案例。

基本案例:调用无参方法

public class User {
    private String name;
    public User(String name) {
        this.name = name;
    }
    public void sayHello() {
        System.out.println("Hello, I'm " + name);
    }
    public String getName() {
        return name;
    }
}
import java.lang.reflect.Method;
public class ReflectionExample1 {
    public static void main(String[] args) throws Exception {
        // 创建对象
        User user = new User("张三");
        // 获取Class对象
        Class<?> clazz = user.getClass();
        // 获取方法(无参方法)
        Method sayHelloMethod = clazz.getMethod("sayHello");
        // 调用方法
        sayHelloMethod.invoke(user);  // 输出:Hello, I'm 张三
    }
}

带参数的方法调用

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }
    public double divide(double a, double b) {
        if (b == 0) {
            throw new IllegalArgumentException("除数不能为0");
        }
        return a / b;
    }
    private String formatResult(String operation, double result) {
        return operation + "的结果是: " + result;
    }
}
import java.lang.reflect.Method;
public class ReflectionExample2 {
    public static void main(String[] args) throws Exception {
        Calculator calc = new Calculator();
        Class<?> clazz = calc.getClass();
        // 调用带int参数的方法
        Method addMethod = clazz.getMethod("add", int.class, int.class);
        Object result1 = addMethod.invoke(calc, 10, 20);
        System.out.println("加法结果: " + result1);  // 30
        // 调用带double参数的方法
        Method divideMethod = clazz.getMethod("divide", double.class, double.class);
        Object result2 = divideMethod.invoke(calc, 10.0, 3.0);
        System.out.println("除法结果: " + result2);  // 3.3333333333333335
        // 调用私有方法
        Method formatMethod = clazz.getDeclaredMethod("formatResult", String.class, double.class);
        formatMethod.setAccessible(true);  // 设置可访问私有方法
        Object result3 = formatMethod.invoke(calc, "加法", 15.0);
        System.out.println(result3);  // 加法的结果是: 15.0
    }
}

静态方法调用

public class StringUtil {
    public static boolean isEmpty(String str) {
        return str == null || str.trim().isEmpty();
    }
    public static String capitalize(String str) {
        if (isEmpty(str)) return str;
        return str.substring(0, 1).toUpperCase() + str.substring(1).toLowerCase();
    }
}
import java.lang.reflect.Method;
public class ReflectionExample3 {
    public static void main(String[] args) throws Exception {
        // 获取Class对象
        Class<?> clazz = StringUtil.class;
        // 调用静态方法(不需要实例对象)
        Method isEmptyMethod = clazz.getMethod("isEmpty", String.class);
        Object result1 = isEmptyMethod.invoke(null, "");  // 静态方法第一个参数传null
        System.out.println("是否为空: " + result1);  // true
        // 调用另一个静态方法
        Method capitalizeMethod = clazz.getMethod("capitalize", String.class);
        Object result2 = capitalizeMethod.invoke(null, "hello world");
        System.out.println("首字母大写: " + result2);  // Hello world
    }
}

处理异常的方法调用

public class DataProcessor {
    public void processData(String data) throws Exception {
        if (data == null || data.isEmpty()) {
            throw new Exception("数据不能为空");
        }
        System.out.println("处理数据: " + data);
    }
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class ReflectionExample4 {
    public static void main(String[] args) {
        DataProcessor processor = new DataProcessor();
        try {
            Method processMethod = DataProcessor.class.getMethod("processData", String.class);
            // 正常调用
            processMethod.invoke(processor, "测试数据");
            // 会抛出异常
            processMethod.invoke(processor, "");
        } catch (InvocationTargetException e) {
            // 获取原始异常
            Throwable originalException = e.getCause();
            System.out.println("原始异常: " + originalException.getMessage());
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

实际应用:动态调用任意对象的方法

import java.lang.reflect.Method;
import java.util.*;
public class DynamicMethodInvoker {
    /**
     * 动态调用对象的指定方法
     */
    public static Object invokeMethod(Object obj, String methodName, Object... args) throws Exception {
        Class<?> clazz = obj.getClass();
        Class<?>[] paramTypes = new Class[args.length];
        // 获取参数类型
        for (int i = 0; i < args.length; i++) {
            paramTypes[i] = args[i].getClass();
        }
        // 获取方法
        Method method = clazz.getMethod(methodName, paramTypes);
        // 调用方法
        return method.invoke(obj, args);
    }
    public static void main(String[] args) {
        try {
            // 测试不同的对象和方法
            String str = "Hello World";
            // 调用字符串的 length 方法
            Object length = invokeMethod(str, "length");
            System.out.println("字符串长度: " + length);  // 11
            // 调用字符串的 substring 方法
            Object subStr = invokeMethod(str, "substring", 0, 5);
            System.out.println("子字符串: " + subStr);  // Hello
            // 调用 List 的 add 方法
            List<String> list = new ArrayList<>();
            invokeMethod(list, "add", "item1");
            invokeMethod(list, "add", "item2");
            System.out.println("List内容: " + list);  // [item1, item2]
            // 调用 List 的 size 方法
            Object size = invokeMethod(list, "size");
            System.out.println("List大小: " + size);  // 2
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

批量执行测试方法

import java.lang.reflect.Method;
public class TestRunner {
    public static void runTests(Object testObject) {
        Class<?> clazz = testObject.getClass();
        Method[] methods = clazz.getMethods();
        for (Method method : methods) {
            // 只执行以 "test" 开头的方法
            if (method.getName().startsWith("test") && method.getParameterCount() == 0) {
                try {
                    System.out.println("执行测试: " + method.getName());
                    method.invoke(testObject);
                    System.out.println("测试通过: " + method.getName());
                } catch (Exception e) {
                    System.out.println("测试失败: " + method.getName() + " - " + e.getCause().getMessage());
                }
                System.out.println("------------------------");
            }
        }
    }
    public static void main(String[] args) {
        // 创建测试对象并运行测试
        MyTest testObject = new MyTest();
        runTests(testObject);
    }
}
// 测试类
class MyTest {
    public void testAddition() {
        System.out.println("1 + 1 = " + (1 + 1));
    }
    public void testString() {
        System.out.println("字符串拼接测试: " + "Hello" + " World");
    }
    public void testFailedCase() {
        throw new RuntimeException("这是一个失败的测试");
    }
    public void notATest() {
        System.out.println("这个方法不会被反射调用");
    }
}

关键要点

  1. 获取Method对象

    • getMethod():获取public方法(包括继承的)
    • getDeclaredMethod():获取所有声明的方法(包括private)
  2. 调用方法

    • invoke(对象, 参数...):调用实例方法
    • invoke(null, 参数...):调用静态方法
  3. 处理私有方法

    • 调用setAccessible(true)可以访问private方法
  4. 异常处理

    • 反射调用的异常会被包装在InvocationTargetException
    • 需要使用getCause()获取原始异常
  5. 性能考虑

    • 反射调用比直接调用慢
    • 如果需要频繁调用,考虑缓存Method对象

这些案例覆盖了大部分的反射方法调用场景,你可以根据实际需求选择使用。

抱歉,评论功能暂时关闭!