Java使用deequ时Analyzer泛型警告与addAnalyzer传参错误如何解决?
问题解答
你的判断是否正确
你的判断完全正确。DoubleMetric确实实现了Metric接口,报错和类型继承关系无关,是Java泛型的型变规则和编辑器静态检查逻辑导致的矛盾。
为什么raw类型的方法签名会提示泛型要求
你看到的addAnalyzer方法签名是Scala代码编译为Java字节码后生成的兼容签名,Deequ的Analyzer类本身是带两个泛型参数的Scala泛型类,IntelliJ等编辑器做静态检查时,会读取类的原始泛型定义,自动推断方法入参的期望类型为Analyzer<?, ? extends Metric<?>>,因此会对不符合泛型约束的入参报错。
Java泛型默认是不变的,你声明的Analyzer<NumMatchesAndCount, DoubleMetric>中第二个泛型参数是具体的DoubleMetric,即使它实现了Metric接口,也无法直接匹配Analyzer<?, Metric<?>>的泛型要求。
解决方案(三种任选即可)
- 方案1:直接用具体实现类声明变量(最推荐,无任何告警)
不需要手动向上转型为Analyzer,直接用PatternMatch类型接收实例即可:PatternMatch emailPatternAnalyzer = new PatternMatch("email", Patterns.EMAIL(), option); analysisBuilder.addAnalyzer(emailPatternAnalyzer); - 方案2:给Analyzer加上适配的通配符泛型
要是需要统一用Analyzer类型管理多个分析器,可以用通配符声明泛型:Analyzer<?, ? extends Metric<?>> analyzer = new PatternMatch("email", Patterns.EMAIL(), option); analysisBuilder.addAnalyzer(analyzer); - 方案3:忽略raw类型告警
运行时泛型会擦除,你最开始的raw类型写法本身可以正常执行,只需要加注解忽略编辑器告警即可:@SuppressWarnings("rawtypes") Analyzer analyzer = new PatternMatch("email", Patterns.EMAIL(), option); analysisBuilder.addAnalyzer(analyzer);
内容的提问来源于stack exchange,提问作者Ruchit
相关产品推荐
相关产品推荐

