如何将通配符Function接口映射为带类型的Function接口
解决方案
核心思路
不用修改现有masterAccessor,也不用为每种类型单独写专属主访问器,只需要实现一个泛型类型转换工具方法,就能把masterAccessor返回的Function<Context, Optional<?>>安全转换成指定类型的Function<Context, Optional<T>>:
- 原访问器返回值类型匹配目标类型时,保留结果
- 类型不匹配或结果为空时,返回
Optional.empty()
实现转换工具方法
public static <T> Function<Context, Optional<T>> castAccessor( Function<Context, Optional<?>> rawAccessor, Class<T> targetType) { return ctx -> rawAccessor.apply(ctx) .filter(targetType::isInstance) .map(targetType::cast); }
代码说明
- 类型校验:通过
filter(targetType::isInstance)判断Optional中的值是否属于目标类型 - 安全转换:用
targetType::cast替代强制转换,消除unchecked警告 - 通用适配:泛型
<T>支持所有已有的(String、Long)和未来扩展的类型
业务代码中使用示例
1. 获取原始访问器
从masterAccessor拿到对应名称的原始函数:
Function<Context, Optional<?>> rawReasonAccessor = masterAccessor("reason");
2. 转换为指定类型访问器
比如转换成String类型:
Function<Context, Optional<String>> stringReasonAccessor = castAccessor(rawReasonAccessor, String.class);
如果reason()实际返回的是Long类型,转换后的访问器会自动返回Optional.empty()。
3. 传入目标方法
直接将转换后的访问器传入stringEquals或通用predicate方法:
// 调用stringEquals示例 Predicate<Context> reasonEqualsTest = stringEquals(stringReasonAccessor, "test_reason"); // 调用通用predicate示例(以Long类型为例) Function<Context, Optional<?>> rawIdAccessor = masterAccessor("id"); Function<Context, Optional<Long>> longIdAccessor = castAccessor(rawIdAccessor, Long.class); Predicate<Context> idGreaterThan5 = predicate(longIdAccessor, id -> id > 5);
方案优势
- 完全不改动现有
masterAccessor方法 - 无需重复实现各类型专属主访问器
- 后续扩展新类型时,仅需传入对应
Class对象即可,无需修改转换工具 - 类型转换过程安全,避免强制转换引发的运行时异常
内容的提问来源于stack exchange,提问作者AHungerArtist
相关产品推荐
相关产品推荐

