Java 如何在Iterable.forEach中处理IOException?
我正在研究将一组对象写入文件的方法。为什么下面使用Iterable.forEach()的实现无法编译?在Eclipse中,我得到的消息是没有处理IOException。这尤其令人困惑,因为我似乎正在处理IOExceptionJava 如何在Iterable.forEach中处理IOException?,java,foreach,lambda,java-8,checked-exceptions,Java,Foreach,Lambda,Java 8,Checked Exceptions,我正在研究将一组对象写入文件的方法。为什么下面使用Iterable.forEach()的实现无法编译?在Eclipse中,我得到的消息是没有处理IOException。这尤其令人困惑,因为我似乎正在处理IOException public void write(Iterable<?> objects) { try (BufferedWriter bw = new BufferedWriter( new OutputStreamWriter(
public void write(Iterable<?> objects) {
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"), "UTF-8"));) {
objects.forEach((o) -> bw.write(o.toString())); //Unhandled exception type IOException
} catch (IOException e) {
//handle exception
}
}
我已经检查了和文档,它们似乎都没有建议如何解决这个问题。问题是接口
消费者中的方法accept
没有声明抛出异常。因此,不能使用在lambda中引发选中异常的方法
解决方案是为每个循环使用一个
让我们以匿名类的形式编写lambda:
objects.forEach(new Consumer<Object>() {
public void accept(Object o) {
bw.write(o.toString());
}
});
(另见。)
保证像该示例中那样包装和抛出异常有效:
操作引发的异常将转发给调用方
但是,最好不要在抛出选中异常的上下文中使用forEach
,或者在lambda的主体中捕获并处理异常。如果您只关心将字符串打印到文件中,使用PrintStream
或PrintWriter
代替其他Writer
类。PrintStream
和PrintWriter
的显著特点是它们的打印操作不会抛出IOException
。它们还自动调用对象上的toString
,这使事情变得非常方便:
public void write1(Iterable<?> objects) {
try (PrintStream ps = new PrintStream("printout.txt", "UTF-8")) {
objects.forEach(ps::println);
} catch (IOException ioe) {
// handle
}
}
现在我们需要编写一个函数,将IOConsumer
转换为Consumer
。它通过将捕获的任何IOException
转换为一个UncheckedIOException
,这是一个为此目的创建的异常
static <T> Consumer<T> wrap(IOConsumer<? super T> ioc) {
return t -> {
try {
ioc.accept(t);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
};
}
静态使用者包装(IOConsumer对象){
try(BufferedWriter bw=new BufferedWriter(
新的OutputStreamWriter(
新文件输出流(“out.txt”),“UTF-8”)){
forEach(wrap(o->bw.write(o.toString()));
}捕获(IOException |未选中异常e){
//处理异常
}
}
通常,如果发生任何异常,我们不会将数据写入文件。记住这一点,我们可以编写自己的消费者,将选中的异常包装为未选中的异常
。这样就可以避免编译时错误。
请尝试下面的代码
import java.io.*;
import java.util.*;
public class HelloWorld{
public static void main(String []args){
write(Arrays.asList(1,2,3));
}
public static void write(Iterable<?> objects) {
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("c:\\out.txt"), "UTF-8"))) {
objects.forEach(o->myConsumerThrowsRuntimeException(bw,o.toString())); //Unhandled exception type IOException
} catch (Exception e) {
//handle exception
}
}
public static void myConsumerThrowsRuntimeException(Writer writer , String data){
try{
writer.write(data);
}catch(IOException e){
throw new RuntimeException("Cannot write Data error is "+e.getMessage());
}
}
}
import java.io.*;
导入java.util.*;
公共类HelloWorld{
公共静态void main(字符串[]args){
写(Arrays.asList(1,2,3));
}
公共静态无效写入(Iterable对象){
try(BufferedWriter bw=new BufferedWriter(
新的OutputStreamWriter(
新文件输出流(“c:\\out.txt”),“UTF-8”)){
objects.forEach(o->myConsumerThrowsRuntimeException(bw,o.toString());//未处理的异常类型IOException
}捕获(例外e){
//处理异常
}
}
公共静态void myConsumerThrowRuntimeException(编写器、字符串数据){
试一试{
writer.write(数据);
}捕获(IOE异常){
抛出新的RuntimeException(“无法写入数据错误为”+e.getMessage());
}
}
}
您能通过命令行编译它吗?eclipse的哪个版本?唉,这是当前lambda实现的缺点之一,我已经不止一次地抨击过它了!:)这就是我要找的。谢谢
interface IOConsumer<T> {
void accept(T t) throws IOException;
}
static <T> Consumer<T> wrap(IOConsumer<? super T> ioc) {
return t -> {
try {
ioc.accept(t);
} catch (IOException ioe) {
throw new UncheckedIOException(ioe);
}
};
}
public void write2(Iterable<?> objects) {
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"), "UTF-8"))) {
objects.forEach(wrap(o -> bw.write(o.toString())));
} catch (IOException|UncheckedIOException e) {
//handle exception
}
}
import java.io.*;
import java.util.*;
public class HelloWorld{
public static void main(String []args){
write(Arrays.asList(1,2,3));
}
public static void write(Iterable<?> objects) {
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("c:\\out.txt"), "UTF-8"))) {
objects.forEach(o->myConsumerThrowsRuntimeException(bw,o.toString())); //Unhandled exception type IOException
} catch (Exception e) {
//handle exception
}
}
public static void myConsumerThrowsRuntimeException(Writer writer , String data){
try{
writer.write(data);
}catch(IOException e){
throw new RuntimeException("Cannot write Data error is "+e.getMessage());
}
}
}