错误:未报告的异常IOException;必须被捕获或声明被抛出流()

时间:2016-04-16 23:52:17

标签: java file lambda

我正在尝试编写文件,这是代码:

    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:错误:未报告的异常IOException;必须被抓住或宣布被抛出              .forEachOrdered(X-&GT; writer.write(x.getName()));

我的疑问:即使我在使用.forEachOrdered()的方法中声明IOException,我也无法使用它,因为我在.forEachOrdered()(它是消费者)中定义的方法没有& #39; t声明它?我不知道我是否清楚,但也许你可以推断一下只看代码。感谢。

注意:该表是带有团队的声明静态列表。

2 个答案:

答案 0 :(得分:2)

您可以捕获IOException并重新抛出包含在UncheckedIOException中的内容,如下所示:

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

如果抛出IOException,流将不会继续处理。

在流之外,您应该将捕获更改为

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

您可以创建方便的功能类型来处理try / catch,例如

@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())));

答案 1 :(得分:1)

问题是forEachOrdered的签名需要ConsumerConsumer并未声明其accept方法可以抛出任何已检查的异常。

JLS 11.2.3说:

  

如果一个lambda体可以在E是一个已检查的异常类时抛出一些异常类E并且E不是在lambda表达式所针对的函数类型的throws子句中声明的某个类的子类,那么这是一个编译时错误。

因此,IOException必须由lambda本身捕获。建议的解决方案是:

  • 在lambda中捕获并处理它,或
  • 在lambda中捕获它并重新抛出包装在未经检查的异常中,然后在外层捕获/处理包装的异常。 @Hank D的回答说明了这一点。

在lambda中处理IOException的问题在于&#34;对于每个&#34;将继续运行。