事情是这样婶的,在一次对后端框架进行改造时,为了使基类控制器(BaseController)能够适配 Mybatis-Plus-Join 进行联表查询,在复杂的泛型结构上继承了IQueryAction(这个接口主要实现 Mybatis-Plus-Join 所实现的各种接口),在 IQueryAction 继承的 QueryJoin<Children,Entity> 链接查询接口后,需要实现其内部接口:
<T> Children join(String var1, Class<T> var2, String var3, BiConsumer<JoinAbstractLambdaWrapper<Entity, ?>, Children> var4);
而实现类重写下来的方法大致如下:
public <T> IQueryAction<R, VO> join(String keyWord, Class<T> clazz, String alias, BiConsumer<JoinAbstractLambdaWrapper<VO, ?>, IQueryAction<R, VO>> consumer) {
return null;
}
这时在方法体内调用 MPJLambdaWrapper 的 join 方法,类型是不匹配的,例:
this.wrapper.join(keyWord, clazz, alias, consumer);
# wrapper 是 MPJLambdaWrapper 的实例
# 这样调用将找不到方法,因为类型不匹配
# MPJLambdaWrapper 实现的 BiConsumer 类型是 BiConsumer<JoinAbstractLambdaWrapper<VO, ?>, MPJLambdaWrapper<R>>,我们这里是 IQueryAction<R, VO>>
这时候就需要对 BiConsumer 进行类型转换,将 MPJLambdaWrapper 转换为 IQueryAction,最终实现如下:
# 这里需要将 IQueryAction<R, VO>> consumer 进行转换
# 这里的 this.childThis 就是实现类子类本身,也就是 IQueryAction
this.wrapper.join(keyWord, clazz, alias, (BiConsumer) (wrapper, mpjWrapper) -> {
// 进行转换,将MPJLambdaWrapper转换为IQueryAction
consumer.accept((JoinAbstractLambdaWrapper<VO, ?>) wrapper, this.childThis);
});
代码参考 akim-boot 框架(框架自用,尚未开源)的 com.akim.boot.starter.boost.core.action.impl.AbstractQueryAction。