[英]Checked exceptions thrown from within lambda expressions
你能解釋為什么必須從lambda表達式中捕獲檢查異常嗎? 換句話說,為什么以下代碼無法編譯...
public void doSomething(ObjectInputStream istream) throws IOException {
// The read method throws an IOException.
IntStream.range(0, 10).forEach(i -> someList.add(read(istream)));
}
但是這個會嗎?
public void doSomething(ObjectInputStream istream) throws IOException {
IntStream.range(0, 10).forEach(i -> {
try {
// The read method throws an IOException.
someList.add(read(istream));
}
catch (IOException ioe) {
// Callee has to handle checked exception, not caller.
}
});
}
看起來被調用者現在必須處理被拋出的任何已檢查異常而不是調用者。
問題不在於lambda表達式,而是它正在實現的接口。 請記住,lambda表達式基本上只是實現給定接口的匿名類的簡寫。
在這種情況下, forEach
采用java.util.function.Consumer<T>
:
public interface Consumer<T> {
void accept(T t);
...
}
請注意,不聲明accept
拋出任何東西。 這意味着沒有任何實現可以拋出任何東西; 不是命名類,不是匿名類,不是lambda。
您的read
方法似乎拋出IOException
。
IntStream.forEach
的簽名是forEach(IntConsumer action)
,其中IntConsumer
有一個void accept(int value)
方法。 在該上下文中,您的lambda表達式i -> someList.add(read(istream))
等效於:
public class IntConsumerImplementation implements IntConsumer {
ObjectInputStream istream;
public void accept(int i) {
someList.add(read(istream));
};
}
因為read
拋出一個已檢查的異常而無法編譯。
另一方面,如果函數接口定義了lambda表達式,則lambda表達式可能拋出已檢查的異常(消費者或其他java.util
功能接口不是這種情況)。
假設以下組成示例:
@FunctionalInterface
public interface NotAnIntConsumer {
public void accept(int i) throws IOException;
}
現在以下編譯:
forEach(NotAnIntConsumer naic) { ... }
doSomething(ObjectInputStream istream) throws IOException {
IntStream.range(0, 10).forEach(i -> someList.add(read(istream)));
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.