簡體   English   中英

從lambda表達式中拋出的已檢查異常

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM