Kotlin泛型Validator接口在Map中使用的类型不匹配问题求助
解决Kotlin泛型类型不匹配问题:Validator与Request的协变/逆变处理
你的代码中validatorProvider.get(action).validate(paymentCmd)出现类型不匹配,核心原因是ValidatorProvider中固定的Validator<Request<Any?>, Any?>无法兼容更具体的T: Request<R>类型参数。通过调整泛型的协变/逆变约束,以及修改Provider的泛型声明,可以彻底解决这个问题。
1. 调整Validator接口的泛型方向
Validator的validate方法中,T是输入参数(仅被消费),R是返回结果(仅被生产)。给泛型加上对应的协变/逆变标记,让类型适配更灵活:
interface Validator<in T : Request<R>, out R> { fun validate(paymentCmd: T): Pair<ValidationResult, R> }
in T:逆变,允许用接受父类型的Validator处理子类型的Request;out R:协变,允许返回更具体的R类型,适配上层方法的返回值要求。
2. 修改ValidatorProvider的泛型声明
将原来固定的类型改为通配符兼容形式,并调整register/get方法的泛型签名,确保能正确存储和获取对应类型的Validator:
class ValidatorProvider { private val validators: MutableMap<PaymentAction, Validator<in Request<*>, *>> = mutableMapOf() fun <T : Request<R>, R> register(action: PaymentAction, validator: Validator<T, R>) { validators[action] = validator } @Suppress("UNCHECKED_CAST") fun <T : Request<R>, R> get(action: PaymentAction): Validator<T, R> { return validators[action] as? Validator<T, R> ?: throw IllegalArgumentException("No validator registered for action: $action") } }
Validator<in Request<*>, *>作为Map存储类型,利用逆变特性兼容所有Request子类的Validator;- register方法通过泛型参数约束,确保传入的Validator类型合法;
- get方法通过类型转换(业务上需保证Action与Validator类型一一对应)返回目标类型的Validator,消除类型不匹配问题。
3. 验证PaymentServiceImpl的调用
修改后的Provider在业务代码中可以直接使用,无需额外类型转换:
@Component class PaymentServiceImpl(private val validatorProvider: ValidatorProvider, private val handlerProvider: HandlerProvider ): PaymentService { override fun <T: Request<R>, R> process(paymentCmd: T, action: PaymentAction): R { val validator = validatorProvider.get<T, R>(action) val result = validator.validate(paymentCmd) if(result.first.status == ValidationStatus.FAILED){ return result.second } return handlerProvider.get(action).process(paymentCmd) } }
内容的提问来源于stack exchange,提问作者Luis Mauri
相关产品推荐
相关产品推荐

