2017-12-10 21 views
0

は、誰かが私に次のコード行を説明していただけますコンパイル時に決定したようです。 PipelineのApplyメソッドは、T extends POutputを返します。 インターフェイスPOutputには適用メソッドがありません。この場合適用チェーン戻り値の型は

、それだけようTextIO.read()が起こる。(...)からPOUTPUTとしてPCollectionを返し、それが適用方法を有します。

しかし、これまでのパイプライン契約が行くように、私達はちょうどPOUTPUTが返されることを知っています。 コンパイラは、最初の適用に渡された引数の型をどのようにチェックするのですか?私がJavaをコーディングしていたときに思い出したことから、それは実行時にしか見られません。

+0

タイプTはコンパイル時に認識されます。 –

+0

私が知っていると矛盾する - コンパイル時にTがその型に置き換えられた - 私たちのケースではPOutput – Andrei

答えて

0

署名である:

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

これはPOutputを拡張するすべての可能なタイプOutputTため、この方法は(String, PTransform<? super PBegin, OutputT>)戻るOutputTに適用可能であることを意味します。

TextIO.read()は、TextIO.Readを返します。PTransform<PBegin, PCollection<String>>を返します。それはPTransform<? super PBegin, OutputT>一致します

  • タイプPBeginは自明PBegin
  • タイプPCollection<String>のスーパータイプですのでPOutput

拡張し、.apply()方法は、置換OutputT = PCollection<String>と、適用されます。 OutputTの実際の値を.apply()の署名に代入した後、戻り値はPCollection<String>です。

何が(POutputに置き換えられるOutputT)を型消去中に起こる言っている - Pipeline.apply()の種類消去された署名がPOutput apply(String, PTransform)です。コンパイルされたバイトコードのPipelineの署名は、JVMが実際にそれを実行するときに関係しています。しかし、型消去は型検査の後ではなく、前に行われます。そうでなければ、ジェネリックを使用するほとんどすべてのJavaプログラムがコンパイルに失敗します。

これはまさにあなたがArrays.asList(1, 2, 3)を呼び出すときに起こる同じものである - それは、型消去署名がList asList(Object[])であっても、List<Integer>はなくList<Object>またはList返します。

+0

Okだから、明示的なキャストが行われてから型消去が適用されると言っている。 は、だから私は見る、の.classファイルをチェック: 18 INVOKEVIRTUAL org.apache.beam.sdk.Pipeline.apply(org.apache.beam.sdk.transforms.PTransform):org.apache.beam.sdk.values.POutput [7] 21チェックキャストorg.apache.beam.sdk.values.PCollection [8] [....]] 36 invokevirtual org.apache.beam.sdk.values.PCollection.apply(java.lang.String、org.apache.beam.sdk.transforms.PTransform):org.apache.beam.sdk.values.POutput [ 13] そう...あなたは正しい!ありがとう! – Andrei