日拱一卒:Java 反射之动态调用方法
2023-09-21 本文已影响0人
Tinyspot
1. 获取方法
/**
* all the public methods
* including inherited from superclasses and superinterfaces.
*/
Method[] methods = clazz.getMethods();
/**
* all the declared methods, including public, protected, default (package) access, and private methods,
* but excluding inherited methods.
*/
Method[] declaredMethods = clazz.getDeclaredMethods();
1.1 打印方法信息
@Test
public void reflection() throws ClassNotFoundException {
// Class<?> clazz = GreetService.class;
Class<?> clazz = Class.forName("com.example.concrete.starter.service.GreetService");
Method[] methods = clazz.getMethods();
for (Method method : methods) {
System.out.println(method.toString());
}
}
打印信息
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greeting(com.example.concrete.common.domain.UserDTO,java.lang.String)
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greet(java.lang.String,java.lang.String)
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greet(java.lang.String)
public abstract java.lang.String com.example.concrete.starter.service.GreetService.greet()
2. 反射调用方法
@Service
public class GreetServiceImpl implements GreetService {
@Override
public String greeting(UserDTO userDTO, String env) {
return "greeting run..." + JSON.toJSONString(userDTO) + "; " + env;
}
@Override
public String greet() {
return "greet...";
}
@Override
public String greet(Integer value) {
return "Integer:" + value;
}
@Override
public String greet(String name) {
return "Hello " + name;
}
@Override
public String greet(String name, String myName) {
return "Hello " + name + ", my name is " + myName;
}
}
2.1 动态方法调用
/**
* 1. 获取类的 Class 对象
* 2. 获取 Method 对象:clazz.getMethods()
* 3. method.invoke(Object obj, Object... args)
* - obj 实例对象
* - args 参数值
* 4. 获取实例对象:clazz.newInstance()
*/
@Test
public void invoke() throws Exception {
Object result = null;
// Class<?> clazz = GreetServiceImpl.class;
Class<?> clazz = Class.forName("com.example.concrete.starter.service.impl.GreetServiceImpl");
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet()")) {
result = method.invoke(clazz.newInstance());
System.out.println(result);
} else if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String)")) {
result = method.invoke(clazz.newInstance(), "xing");
System.out.println(result);
} else if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String,java.lang.String)")) {
result = method.invoke(clazz.newInstance(), "Alice", "xing");
System.out.println(result);
} else if (method.toString().equals("public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greeting(com.example.concrete.common.domain.UserDTO,java.lang.String)")) {
result = method.invoke(clazz.newInstance(), new UserDTO("xing", 20), "Local");
System.out.println(result);
}
}
}
2.2 动态参数组装
@Test
public void invoke() throws Exception {
Class<?> clazz = Class.forName("com.example.concrete.starter.service.impl.GreetServiceImpl");
Object result = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet()", new ArrayList<>());
Object result1 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.Integer)", Arrays.asList("1001"));
Object result2 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String)", Arrays.asList("xing"));
Object result3 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl.greet(java.lang.String,java.lang.String)", Arrays.asList("Alice", "xing"));
Object result4 = invokeMethod(clazz, "public java.lang.String com.example.concrete.starter.service.impl.GreetServiceImpl" +
".greeting(com.example.concrete.common.domain.UserDTO,java.lang.String)", Arrays.asList("{\"age\":20,\"name\":\"xing\"}", "Local"));
System.out.println(result4);
}
方法调用
private Object invokeMethod(Class<?> clazz, String methodSign, List<String> arguments) throws Exception {
Method[] methods = clazz.getMethods();
for (Method method : methods) {
// 实例对象
Object instance = clazz.newInstance();
Class<?>[] parameterTypes = method.getParameterTypes();
// System.out.println(method.toString());
if (method.toString().equals(methodSign)) {
return method.invoke(instance, assemblyArgs(arguments, parameterTypes));
}
}
return null;
}
/**
* 参数组装
* @param arguments 参数值
* @param parameterTypes 参数类型
* @return
*/
private Object[] assemblyArgs(List<String> arguments, Class<?>[] parameterTypes) {
List<Object> args = new ArrayList<>();
for (int i = 0; i < arguments.size(); i++) {
args.add(getArgValue(parameterTypes[i], arguments.get(i)));
}
return args.toArray();
}
private static Object getArgValue(Class<?> parameterType, String arg) {
if (StringUtils.isBlank(arg)) {
return null;
}
arg = StringUtils.trim(arg);
if (parameterType.equals(String.class)) {
return arg;
}
if (parameterType.equals(Integer.class)) {
return Integer.valueOf(arg);
}
if (parameterType.equals(Date.class)) {
if (arg.length() == 10) {
// 例如:2023-01-01
arg += " 00:00:00";
}
return DateUtil.parseToDateTime(arg);
}
// 转为对象
return JSON.parseObject(arg, parameterType);
}