2017-06-28 7 views
3

try-with-resourceステートメントはラムダのタイプを推論できます。enhanced-forステートメントがラムダのタイプを推論できないのはなぜですか?

try (Closeable 最後に実行 =() -> System.out.print("終了")) { 
    System.out.println("開始"); 
} 

しかし、enhanced-forステートメントはできません。

Iterator<String> 繰り返し = Arrays.asList("いち", "に", "さん").iterator(); 
for (String 文字列 :() -> 繰り返し) // compile error! 
    System.out.println(文字列); 

このように記述する必要があります。

Iterator<String> 繰り返し = Arrays.asList("いち", "に", "さん").iterator(); 
for (String 文字列 : (Iterable<String>)() -> 繰り返し) 
    System.out.println(文字列); 

なぜですか?

+2

ラムダを 'Iterable'インタフェースの実装にしたいとコンパイラがどのように知っていますか? 'for'ステートメントは' Iterable'を必要としないので、そこから推論することはできません。 JLS [14.14.2。拡張されたfor文](http://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-14.14.2)には次のように書かれています。*式の型はIterable **または配列型**。*これは、推論エンジンが処理できる以上のものです。 – Andreas

+0

@Andreasどのラムダ式も 'String []'型ではありません。したがって、javacは 'Iterable 'を推論することができます。 – saka1029

答えて

0

TRY-と-resorceあなたが期待される結果の型宣言しているので、推測することができます。

try (Closeable 最後に実行 =() -> System.out.print("終了")) { 
    ^^^^^^^^^ 

のjavacこのラムダがCloseableに変換する必要があることを、その変数の割り当てからターゲット・タイプを知っています。しかし、そのようなターゲットタイプの情報はありません。複数のターゲット・タイプがあるかもしれません。もちろん

  • public interface StringIterable extends Iterable<String>
  • public interface WeridIterable extends Iterable<String>
    • Iterable<String> ...

    あなたが明示的に与えなければならないので、可能なターゲットタイプの任意の数がありますが、あなたはtry-with-resourceの場合のように、(Iterable<String>)を使用します。

  • +0

    また 'String []'もあります。 – saka1029

    +0

    @ saka1029ラムダをどのようにして配列型にしますか? – glee8e

    +0

    @VinceEmigh Closeable yesには任意の数の可能なサブタイプがありますが、* ResourceSpecification *の部分に明示的に指定したので、コンパイラーは混乱しません。 – glee8e

    関連する問題