处理反射中由于目标方法重载导致调用失败问题(判断方法唯一)
方法签名
下面是一个使用场景
package com.example.demo.retry;
import java.util.List;
/**
* @Description: 反射调用方法,方法名一致情况下
* @Date: 2019/11/22
*/
public class MethodReloadTest {
/*
* @Description: 方法签名和方法名字与参数列表有关,与返回值、修饰符无关
* @param: []
* @return: void
* @Date: 2019/11/22
*/
public void work() {
System.out.println("work无参。。。。。。");
TaskHandler.invokeHandler(new Task(MethodReloadTest.class.getName(),
"work",
new Object[0]));
}
public void work(String str) {
System.out.println("work有1参。。。。。。");
TaskHandler.invokeHandler(new Task(MethodReloadTest.class.getName(),
"work",
new Object[str]));
}
public void work(int number, String name, List<String> idList) {
System.out.println("work有3参。。。。。。");
TaskHandler.invokeHandler(new Task(MethodReloadTest.class.getName(),
"work",
new Object[number,name,idList]));
}
}
/**
* 调用时的任务实体,用来携带方法信息
*/
public class Task {
private String targetClass;
private String targetMethod;
private Object[] args;//方法参数列表
public Task(String targetClass, String targetMethod, Object[] args) {
this.targetClass = targetClass;
this.targetMethod = targetMethod;
this.args = args;
}
public String getTargetClass() {
return targetClass;
}
public void setTargetClass(String targetClass) {
this.targetClass = targetClass;
}
public String getTargetMethod() {
return targetMethod;
}
public void setTargetMethod(String targetMethod) {
this.targetMethod = targetMethod;
}
public Object[] getArgs() {
return args;
}
public void setArgs(Object[] args) {
this.args = args;
}
}
调用时进行判断
public class TaskHandler {
public static void invokeHandler(Task t) {
try {
Class<?> aClass = Class.forName(t.getTargetClass());
String targetMethod = t.getTargetMethod();
Object targetObj = aClass.newInstance();
// 拿到所有方法
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method method : declaredMethods) {
logger.info("当前方法名:" + method.getName());
method.setAccessible(true);
// 可能存在方法重载,导致方法名一致的情况
if (null != method.getName() && targetMethod.equals(method.getName())) {
Parameter[] parameters = method.getParameters();
if (compareArray(parameters, t.getArgs())) {
method.invoke(targetObj, t.getArgs());
}
}
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
System.out.println(e.getCause());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/*
* @Description: 比较参数列表是否相等
* @param: [objects1, objects2]
* @return: boolean
* @Date: 2019/11/22
*/
public static boolean compareArray(Parameter[] objects1, Object[] objects2) {
if(objects1.length == 0 && objects2.length == 0) {
return true;
}
if(objects1.length == 0 || objects2.length == 0) {
return false;
}
List<String> list1 = Arrays.stream(objects1)
.filter((obj) -> obj == null ? false : true)
.map((obj1) -> {
if (obj1.getType().isPrimitive()) {
return getObjectType(obj1.getType().getTypeName());
} else {
return obj1.getType().getTypeName().toString();
}
})
.collect(Collectors.toList());
List<String> list2 = Arrays.stream(objects2)
.filter((obj) -> obj == null ? false : true)
.map((obj1) -> obj1.getClass().getTypeName())
.collect(Collectors.toList());
System.out.println("list1:" +list1+"\nlist2:"+list2);
// 两个list引用相同(包括两者都为空指针的情况)
if (list1 == list2) {
return true;
}
// 两个list元素个数不相同
if (list1.size() != list2.size()) {
return false;
}
if (!list1.containsAll(list2)) {
return false;
}
return true;
}
/*
* @Description: 比较参数列表是否相等
* @param: [typeName] 基本类型
* @return: String 返回对应的包装类
* @Date: 2019/11/22
*/
private static String getObjectType(String typeName) {
if ("int".equals(typeName)) {
return "java.lang.Integer";
}
if ("long".equals(typeName)) {
return "java.lang.Long";
}
if ("double".equals(typeName)) {
return "java.lang.Double";
}
if ("float".equals(typeName)) {
return "java.lang.Float";
}
if ("byte".equals(typeName)) {
return "java.lang.Byte";
}
if ("short".equals(typeName)) {
return "java.lang.Short";
}
if ("char".equals(typeName)) {
return "java.lang.Character";
}
if ("boolean".equals(typeName)) {
return "java.lang.Boolean";
}
return null;
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术