2016-04-16 10 views
1

私はここにファイルを書き込もうとしていますが、コードです:エラー:報告されない例外IOException;キャッチまたはストリームにスローされるように宣言されなければなりません()

public static void writeFile(File f, int n) throws IOException{ 
    //reads n teams which go to next phase 

    try(BufferedWriter writer = new BufferedWriter(new FileWriter(f))){ 
     table.stream() 
     .sorted() 
     .limit(n) 
     .forEachOrdered(x->writer.write(x.getName())); 
     /*for(int i=0;i<n;i++){ 
      writer.write(table.get(i).getName()); 
      writer.newLine(); 
     }*/ this if uncommented works great! 
    }catch (IOException e){ 
     e.printStackTrace(); 
    } 
} 

と私がコンパイルしようとすると、私はこのエラーを取得:

Counter.java:123:error:報告されない例外IOException;キャッチされるか、スローされると宣言されなければならない。 .forEachOrdered(x-> writer.write(x.getName()));私が疑問に思うのは、メソッドでIOExceptionを宣言しても、私が.forEachOrdered()(Consumer)の中で定義したメソッドが使用できないため、.forEachOrdered()を使用しています。それを宣言しない?私は明確であるかどうかはわかりませんが、コードを見るだけで何かを推測することができます。ありがとう。

注:この表はチームで宣言された静的リストです。

+0

普通の 'for'ループをやって何が問題になっていますか?シンプルで、はっきりしていて、既に働いています。 –

答えて

1

問題がforEachOrderedのための署名がConsumerを必要としConsumerはそのaccept方法は、任意のチェック例外を投げることができることを宣言していないということです。

JLS 11.2.3は言う:

It is a compile-time error if a lambda body can throw some exception class E when E is a checked exception class and E is not a subclass of some class declared in the throws clause of the function type targeted by the lambda expression.

したがって、IOExceptionはラムダ自体でキャッチしなければなりません。推奨される解決策は以下のとおりです。

  • キャッチとラムダの中にそれを扱う、または
  • キャッチ、それはラムダで、それはその後、キャッチ/外側のレベルでラップされた例外を処理し、チェックされない例外に包まれた再スロー。 @ハンクDの答えはこれを示しています。

ラムダ内でIOExceptionを処理する際の問題は、「for each」が引き続き実行されることです。 IOExceptionがスローされた場合、ストリームは処理を続行しません

.forEachOrdered(x-> { 
    try{ 
     writer.write(x.getName())); 
    } catch (IOException e) { 
     throw new UncheckedIOException(e); 
    } 
} 

2

あなたはIOExceptionをキャッチし、それを再スロー可能性は、このように、UncheckedIOExceptionに包まれました。

ストリームの外

、あなたがあなたがあなたのためのtry/catchの世話をする便利機能タイプを作成することができます

} catch (IOException | UncheckedIOException e) { 
     e.printStackTrace(); 
    } 

にあなたのキャッチを変更する必要があり、

@FunctionalInterface 
public interface CheckedIOConsumer<T> { 

    void accept(T t) throws IOException; 

    static <T> Consumer<T> toUnchecked(CheckedIOConsumer<T> consumer) { 
     return t -> { 
      try { 
       consumer.accept(t); 
      } catch (IOException e) { 
       throw new UncheckedIOException(e); 
      } 
     }; 
    } 
} 

のようなものあなたの端末機能を作るでしょう

.forEachOrdered(toUnchecked(x -> writer.write(x.getName()))); 
関連する問題