
本文介绍在 java 类型擦除限制下,如何为 `rule
Java 的泛型在编译后会经历类型擦除(type erasure),这意味着 Rule、Rule 在运行时都表现为原始类型 Rule,无法直接通过 rule.getClass().getTypeParameters() 等反射方式可靠还原泛型实参。因此,必须显式将类型信息作为元数据保留在实例中,才能在流式处理中安全完成 Rule
✅ 推荐方案:在泛型类中固化 Class 引用
修改 Rule
public class Rule{ public final Class type; protected Rule(Class type) { this.type = Objects.requireNonNull(type); } } // 使用示例 Rule stringRule = new Rule<>(String.class); Rule intRule = new Rule<>(Integer.class);
同理,Datasource
? 类型安全的数据源解析器(DatasourceResolver)
定义一个泛型感知的解析器,避免 Map
public class DatasourceResolver {
private final Map, Datasource>> registry = new HashMap<>();
// 注册:支持任意 T
public void register(Class type, Datasource datasource) {
registry.put(type, datasource);
}
// 类型安全获取:返回精确的 Datasource
@SuppressWarnings("unchecked")
public Datasource resolve(Class type) {
return (Datasource) registry.get(type);
}
} ⚠️ 注意:@SuppressWarnings("unchecked") 是此处必要的(因 Map 存储的是原始 Datasource),但该转换是类型安全的——因为我们只通过 Class 查找,且注册时保证了 Class 与 Datasource 的一致性。
? 在 Stream 中使用:完整示例
List> ruleList = Arrays.asList( new Rule<>(String.class), new Rule<>(Integer.class), new Rule<>(Boolean.class) ); DatasourceResolver resolver = new DatasourceResolver(); resolver.register(String.class, new Datasource () { /* ... */ }); resolver.register(Integer.class, new Datasource () { /* ... */ }); resolver.register(Boolean.class, new Datasource () { /* ... */ }); List
? 进阶建议
- 若 Rule
已存在且不可修改,可考虑使用 匿名子类 + getClass().getGenericSuperclass() 反射提取(仅适用于直接继承 Rule 的匿名类,不推荐用于生产环境,稳定性差); - 更健壮的设计是引入策略接口(如 RuleHandler
),将 Rule 与对应 Datasource 的协作逻辑封装为独立处理器,彻底规避运行时类型匹配; - 对于高频调用场景,可缓存 Class
到 Datasource 的映射,避免重复 resolve() 开销。
总之,在并行泛型层级(如 Rule/Datasource)中实现类型联动,核心在于主动保留类型证据,而非依赖 JVM 擦除后的残余信息。这是 Java 泛型生态中兼顾类型安全与运行时灵活性的标准实践。










