這個問題在這里已經有了答案: 為什么我不能在 Java 8 lambda 運算式中拋出例外?[重復] (2個答案) 7 天前關閉。
在下面的代碼中,我在方法簽名中撰寫了 throws ,但在 Lambda 中再次為write,編譯器給出了錯誤。為什么?
編譯器錯誤:未處理的例外:java.io.IOException
public void saveTodoItems() throws IOException {
try (BufferedWriter outputStream = new BufferedWriter(new OutputStreamWriter(
new FileOutputStream("TodoItems.txt"), StandardCharsets.UTF_8))) {
todoItems.forEach(todoItem -> {
outputStream.write(todoItem.getShortDescription() "\t" //compile error on write
todoItem.getDetail() "\t"
todoItem.getDeadLine() "\n");
});
}
}
uj5u.com熱心網友回復:
請記住,lambda 應該是功能介面的實作。在這種情況下,forEach將功能介面Consumer<T>作為引數。
void forEach(Consumer<? super T> action)
所以你的 lambda 實際上是在Consumer介面中實作單個抽象方法 - accept。此方法未宣告拋出任何例外:
void accept(T t); // no throws clause here at all!
因此,IOException呼叫write可能拋出的 被認為是未處理的。throws您在方法中添加了一個子句這一事實saveTodoItems是無關緊要的。
另一方面,如果您宣告了自己的函式式介面,并且throws在其單個抽象方法中確實有一個子句:
interface IOConsumer<T> {
void accept(T t) throws IOException;
}
可以這樣寫:
IOConsumer<TodoItem> consumer = todoItem -> {
outputStream.write(todoItem.getShortDescription() "\t"
todoItem.getDetail() "\t"
todoItem.getDeadLine() "\n");
};
當然,你不能在 中使用它forEach,因為它只接受 a Consumer,而不接受IOConsumer。write您應該用 try...catch包圍,或查看此處了解更多替代方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/426242.html
