【问题标题】:Chained apply return type seems determined at compile time链式应用返回类型似乎在编译时确定
【发布时间】:2017-12-10 19:50:29
【问题描述】:

谁能给我解释一下下面几行代码:

import org.apache.beam.sdk.Pipeline;
[..]
Pipeline p = Pipeline.create(options);
p.apply(TextIO.read().from("gs://apache-beam-samples/shakespeare/*"))
.apply("ExtractWords", ParDo.of(new DoFn<String, String>() {/* etc */}

我不明白为什么会这样编译。 Pipeline 中的 Apply 方法返回一个 T extends POutput。 接口 POutput 没有任何 apply 方法。

在这种情况下,TextIO.read().from(...) 恰好返回一个 PCollection 作为 POutput,并且 THAT 有一个 apply 方法。

但就 Pipeline 合约而言,我们知道只会返回一个 POutput。 那么编译器如何检查传递给第一个 apply 的参数类型呢?根据我在编写 Java 时的记忆,这只能在运行时看到。

【问题讨论】:

  • 类型 T 在编译时是已知的。
  • 这与我认为我所知道的相矛盾 - 在编译时 T 被替换为它的有界类型 - 在我们的例子中是 POutput

标签: java apache-beam


【解决方案1】:

签名是:

public <OutputT extends POutput> OutputT apply(
    String name, PTransform<? super PBegin, OutputT> root) {
  ...
}

这意味着,对于扩展POutput 的任何可能的类型OutputT,此方法适用于(String, PTransform&lt;? super PBegin, OutputT&gt;) 并返回OutputT

TextIO.read() 返回一个扩展PTransform&lt;PBegin, PCollection&lt;String&gt;&gt;TextIO.Read;它匹配PTransform&lt;? super PBegin, OutputT&gt;:

  • PBegin 类型实际上是 PBegin 的超类型
  • PCollection&lt;String&gt; 类型扩展 POutput

因此,.apply() 方法适用,替换为 OutputT = PCollection&lt;String&gt;。将OutputT的实际值代入.apply()的签名后,返回值为PCollection&lt;String&gt;

你所说的(OutputTPOutput 替换)发生在类型擦除 - Pipeline.apply() 的类型擦除签名是POutput apply(String, PTransform);这就是它在编译后的Pipeline 字节码中的签名,就JVM 而言,在实际执行它时。然而,类型擦除发生在类型检查之后,而不是之前 - 否则几乎所有使用泛型的 Java 程序都将无法编译。

这与调用 Arrays.asList(1, 2, 3) 时发生的事情完全相同 - 它返回 List&lt;Integer&gt; 而不是 List&lt;Object&gt;List,即使类型擦除的签名是 List asList(Object[])

【讨论】:

  • 好的,所以你是说首先进行显式转换,然后应用类型擦除。所以检查 .class 文件,我看到: 18 invokevirtual org.apache.beam.sdk.Pipeline.apply(org.apache.beam.sdk.transforms.PTransform) : org.apache.beam.sdk.values.POutput [7 ] 21 checkcast org.apache.beam.sdk.values.PCollection [8] [....] 36 调用虚拟 org.apache.beam.sdk.values.PCollection.apply(java.lang.String, org.apache.beam .sdk.transforms.PTransform) : org.apache.beam.sdk.values.POutput [13] 所以......你是对的!谢谢!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-07
相关资源
最近更新 更多