可通过自定义@Cmd注解标记方法指令码,运行时构建指令码到Method的映射并结合switch或Map实现高效分发,支持自动注册、安全反射调用及参数校验。

可以通过自定义注解标记方法的指令码,再在运行时用 switch(或等效逻辑)匹配指令码并反射调用对应方法。Java 本身不支持 switch 直接作用于字符串以外的类型(如枚举、int、String),但指令码通常为整数或字符串,因此可结合注解 + 指令码映射实现高效分发。
定义指令码注解
创建一个运行时保留的注解,用于绑定方法与其唯一指令码:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Cmd {
int value(); // 如 0x01, 0x02
// 或 String code() default "";
}
该注解标注在具体业务方法上,例如:
public class CommandHandler {
@Cmd(0x01)
public void handleLogin(Object data) { ... }
@Cmd(0x02)
public void handleLogout(Object data) { ... }
@Cmd(0x03)
public void handleTransfer(Object data) { ... }
}
构建指令码到方法的运行时映射
在初始化阶段(如类加载后、Spring Bean 初始化时),扫描目标类所有带 @Cmd 的方法,缓存为 Map<Integer, Method>。避免每次调用都重复反射查找:
动态切换AI模型以优化成本与性能。当用户发出“eco mode”、“balanced mode”、“smart mode”或“max mode”等模式指令,或使用“/modes status”查询状态及“/modes setup”配置模式时触发。
- 使用
Class.getDeclaredMethods()获取全部方法 - 遍历并检查
method.isAnnotationPresent(Cmd.class) - 提取
method.getAnnotation(Cmd.class).value() - 将
cmdCode → method存入ConcurrentHashMap(线程安全)
用 switch 实现快速分发(推荐:配合枚举或 int 值)
若指令码是整型常量(如 0x01, 0x02),可直接用 switch (cmdCode) 分支跳转,再从缓存 map 中取出方法执行反射调用:
public void dispatch(int cmdCode, Object target, Object... args) throws Exception {
switch (cmdCode) {
case 0x01:
invoke("handleLogin", target, args);
break;
case 0x02:
invoke("handleLogout", target, args);
break;
case 0x03:
invoke("handleTransfer", target, args);
break;
default:
throw new UnsupportedOperationException("Unknown cmd: " + cmdCode);
}
}
private void invoke(String methodName, Object target, Object... args) throws Exception {
Method m = target.getClass().getMethod(methodName, Object.class);
m.setAccessible(true);
m.invoke(target, args);
}
⚠️ 注意:纯 switch 需要编译期已知所有指令码,适合指令集稳定场景;若指令码来自外部(如网络包),建议改用 map 查找 + 反射,更灵活。
增强版:动态注册 + 安全反射调用
实际项目中建议封装统一调度器,支持自动注册、参数适配、异常兜底:
- 提供
register(Class<?> handlerClass)方法完成扫描与注册 - 反射调用前校验方法签名(参数数量、类型兼容性)
- 对
private方法调用前设置setAccessible(true) - 使用
MethodHandle或VarHandle(JDK9+)提升后续调用性能 - 考虑加一层抽象,如
CommandExecutor<T>统一输入输出契约

















