Wil*_*son 10 java foreach lambda checked-exceptions java-8
我正在玩弄将一组对象写入文件的方法.为什么使用Iterable.forEach()的下面的实现不能编译?在Eclipse中,我收到的消息是没有处理IOException.这特别令人困惑,因为我似乎正在处理IOExceptions.
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
}
}
Run Code Online (Sandbox Code Playgroud)
显然,下面的工作.我很感兴趣为什么以上不起作用以及如何解决它.
for (Object o : objects) { bw.write(o.toString()); }
Run Code Online (Sandbox Code Playgroud)
Rad*_*def 11
前体:捕获或指定要求.
让我们将lambda写为匿名类:
objects.forEach(new Consumer<Object>() {
public void accept(Object o) {
bw.write(o.toString());
}
});
Run Code Online (Sandbox Code Playgroud)
我们正在处理吗?应该很清楚,我们不是.
当我们写一个lambda表达式时,我们正在声明一个方法的主体.我们也不能throws为lambda 声明一个子句.
唯一的"解决方法"是做类似以下的事情:
try (BufferedWriter bw = new BufferedWriter(
new OutputStreamWriter(
new FileOutputStream("out.txt"), "UTF-8"));) {
objects.forEach((o) -> {
try {
bw.write(o.toString()));
} catch(IOException kludgy) {
throw new UncheckedIOException(kludgy);
}
});
} catch (UncheckedIOException kludgy) {
IOException cause = kludgy.getCause();
// handle exception
}
Run Code Online (Sandbox Code Playgroud)
(另见UncheckedIOException.)
Iterable.forEach 保证包装和抛出异常,就像在该示例中一样:
操作抛出的异常会转发给调用者.
但是,最好避免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
}
}
Run Code Online (Sandbox Code Playgroud)
如果你担心错误,你可以打电话PrintStream.checkError,虽然这并没有告诉你任何可能发生的错误的细节.
但是,一般的问题仍然是,如果你想在forEach不允许它的上下文(例如)中调用异常抛出方法该怎么办.这只是令人烦恼的处理,尽管只是适度.但是,它确实需要一些设置.假设我们想写一个Consumer抛出一个IOException.我们必须声明我们自己的功能接口:
interface IOConsumer<T> {
void accept(T t) throws IOException;
}
Run Code Online (Sandbox Code Playgroud)
现在我们需要编写一个将IOConsumera 转换为a 的函数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);
}
};
}
Run Code Online (Sandbox Code Playgroud)
有了这些,我们现在可以重写原始示例如下:
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
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
3343 次 |
| 最近记录: |