本文目录导读:

我来给你展示几个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("这个方法不会被反射调用");
}
}
关键要点
-
获取Method对象:
getMethod():获取public方法(包括继承的)getDeclaredMethod():获取所有声明的方法(包括private)
-
调用方法:
invoke(对象, 参数...):调用实例方法invoke(null, 参数...):调用静态方法
-
处理私有方法:
- 调用
setAccessible(true)可以访问private方法
- 调用
-
异常处理:
- 反射调用的异常会被包装在
InvocationTargetException中 - 需要使用
getCause()获取原始异常
- 反射调用的异常会被包装在
-
性能考虑:
- 反射调用比直接调用慢
- 如果需要频繁调用,考虑缓存Method对象
这些案例覆盖了大部分的反射方法调用场景,你可以根据实际需求选择使用。