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

Java 错误:未报告的异常IOException;必须捕获或声明要在流()中抛出,java,file,lambda,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()

我正在尝试编写一个文件,下面是代码:

    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();
    }
}
publicstaticvoidwritefile(文件f,int n)抛出IOException{
//读取进入下一阶段的n个团队
try(BufferedWriter=new BufferedWriter(new FileWriter(f))){
表1.stream()
.已排序()
.限制(n)
.forEachOrdered(x->writer.write(x.getName());
/*for(inti=0;iwriter.write(x.getName())

我的疑问:即使我在使用.forEachOrdered()的方法中声明IOException,我也不能使用它,因为我在.forEachOrdered()中定义的方法(它是一个使用者)没有声明它?我不知道我是否清楚,但也许你可以通过查看代码推断出一些东西。谢谢


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

问题在于
forEachOrdered
的签名需要
使用者
,而
使用者
没有声明其
accept
方法可以抛出任何已检查的异常

说:

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

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

  • 在lambda内捕获并处理,或
  • 在lambda中捕获它,并将其包装在未检查的异常中,然后在外部级别捕获/处理包装的异常。@Hank D的回答说明了这一点

在lambda中处理IOException的问题是“for each”将继续运行。

您可以捕获
IOException
,并将其包装在未选中的IOException中,如下所示:

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