0

我正在使用 deequ 编写分析器。我的编辑正在向我显示此警告,但我不确定如何修复此警告。

网上这个:

Analyzer analyzer = new PatternMatch("email", Patterns.EMAIL(), option);

我在 IntelliJ 中收到此警告。

Raw use of parameterized class 'Analyzer' 

我收到建议更改AnalyzerAnalyzer<NumMatchesAndCount, DoubleMetric>. 当我这样做时,此警告已解决,但是,在这样做时,我在以下行中收到错误:

AnalysisRunBuilder analysisBuilder = AnalysisRunner.onData(table);
analysisBuilder.addAnalyzer(analyzer);

我得到的错误:

Required type:    Analyzer<?,Metric<?>>
Provided:         Analyzer<NumMatchesAndCount, DoubleMetric>

DoubleMetric实现了 Metric 接口 ( public class DoubleMetric implements Metric, Product, Serializable),所以我认为我们不应该得到上述错误。我对吗?

addAnalyzer上一行中的函数签名是:

public AnalysisRunBuilder addAnalyzer(Analyzer analyzer) {
      this.analyzers_$eq((Seq)this.analyzers().$colon$plus(analyzer, .MODULE$.canBuildFrom()));
      return this;
   }

我的疑问是,当函数的签名不期望参数化类Analyzer时,为什么我会收到预期类型为的警告Analyzer<?,Metric<?>>

我的目标是找出如何准确使用addAnalyzer上述功能?在这个函数中,我想传递一个PatternMatch类的实例。该类实现如下:PatternMatch扩展抽象类StandardScanShareableAnalyzer,该抽象类实现接口ScanShareableAnalyzer,该接口又扩展Analyzer类。

4

1 回答 1

0

Deequ 是一个用 Scala 编写的库。虽然从 Java 代码中使用 Scala 库通常是可能的,但并不总是那么简单。

上述方法的代码addAnalyzer看起来像是从字节码反编译器生成的。由于泛型类型擦除,编译字节码中的方法签名会丢失其原始类型参数。但是,类型参数信息包含在字节码的元数据中,允许编译器检查调用。虽然原则上可以在反编译器中重建原始类型(请参阅是否可以将 Java 字节码反编译回原始泛型类型参数),但在这种情况下,它似乎没有。

AnalysisRunBuilder定义的实际原始(Scala)源代码addAnalyzer如下:

def addAnalyzer(analyzer: Analyzer[_, Metric[_]]): this.type = {
  analyzers :+= analyzer
  this
}

在 Scala 中,参数声明的语法采用以下形式:name: Type. 类型参数使用方括号而不是尖括号。通配符使用下划线而不是问号。此方法签名等价于 Java 语法中的此签名:

public AnalysisRunBuilder addAnalyser(Analyzer<?, Metric<?>> analyzer)

与错误消息指示的完全相同。

但是, 的定义DoubleMetric表明它extends Metric[Double]. 我希望问题中的代码能够成功编译。一些 Java IDE 难以检查与 Java 源代码和 Scala 库的兼容性。在 IntelliJ IDEA 中,安装官方Scala 插件可以解决许多此类错误错误的问题。在大多数情况下,使用命令行javac编译器(或调用它的构建工具,如 Maven)可以避免这些问题。

于 2021-08-24T12:09:17.980 回答