通过注解反射优化switch-case的方法调用
需要调用的方法:
public interface IMethodService {
@OperationType(methodType = Methodtype.CHECK)
String check();
@OperationType(methodType = Methodtype.ADD)
String add();
@OperationType(methodType = Methodtype.DELETE)
String delete();
@OperationType(methodType = Methodtype.UPDATE)
String update();
@OperationType(methodType = Methodtype.SELECT)
String select();
正常调用:
如果方法过多(上百),代码易读性,维护行较差
@org.junit.Test
public void testDo() {
IMethodService methodService = new MethodServiceImpl();
Methodtype methodType = Methodtype.UPDATE;
Object result;
switch (methodType) {
case ADD:
result = methodService.add();
break;
case DELETE:
result = methodService.delete();
break;
case UPDATE:
result = methodService.update();
break;
case CHECK:
result = methodService.check();
break;
case SELECT:
result = methodService.select();
break;
default:
result = null;
}
System.out.println(result);
}
通过加注解,使用反射调用方法:
核心思想就是将Methodtype
放入注解value中,通过反射读取,将Methodtype
—method
按照键值对的形式存入map
中
//定义注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface OperationType {
/**
* 需要执行的方法
*/
Methodtype methodType();
}
//增加注解调用方法工具类
public class AnnotationUtils {
private AnnotationUtils() {
}
/**
* 通过反射调用执行方法
*/
public static Object doByAnnotation(Object obj, Class<? extends Annotation> annotation, Methodtype methodKey, Object... inputs) throws InvocationTargetException, IllegalAccessException {
Map<String, AccessibleObject> methodMap = getAnnotatedMethodMap(obj.getClass(), annotation, methodKey.name());
Method method = (Method) methodMap.get(methodKey.name());
if (Objects.isNull(method)) {
System.out.println("未找到对应的方法, operation:{ " + methodKey + "}");
return null;
}
return method.invoke(obj, inputs);
}
/**
* 获取被注解标注的方法map
* @param clazz 目标类
* @param annotation 操作类型注解
* @return 获取被注解标注的方法map
*/
private static Map<String, AccessibleObject> getAnnotatedMethodMap(Class<?> clazz, Class<? extends Annotation> annotation, String methodKey) {
Map<String, AccessibleObject> methodMap = new HashMap<>();
//获取interface
List<Class<?>> interfaces = Arrays.stream(clazz.getInterfaces()).collect(Collectors.toList());
Assert.notNull(interfaces, "interfaces不能为空");
interfaces.forEach(i -> {
Arrays.stream(i.getDeclaredMethods())
.filter(method -> method.isAnnotationPresent(annotation))
.forEach(method -> {
methodMap.put(method.getAnnotation(OperationType.class).methodType().name(),
method);//按照注解的value存入methodMap
});
});
return methodMap;
}
}
//通过注解反射的方式调用
@org.junit.Test
public void testDoByAnnotation() {
IMethodService methodService = new MethodServiceImpl();
Methodtype methodType = Methodtype.UPDATE;
try {
Object result = AnnotationUtils.doByAnnotation(methodService, OperationType.class, methodType);
System.out.println(result);
} catch (InvocationTargetException | IllegalAccessException e) {
e.printStackTrace();
}
}
通过反射调用后续扩展只需要在接口IMethodService
中增加对应的方法和注解参数@OperationType
即可,提高了代码可读性和易维护性
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构