【问题标题】:Checked exceptions thrown from within lambda expressions从 lambda 表达式中抛出的已检查异常
【发布时间】:2015-04-26 18:18:46
【问题描述】:

您能否解释一下为什么必须从 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.
    }
  });
}

现在似乎被调用者必须处理所有抛出的检查异常,而不是调用者。

【问题讨论】:

    标签: java exception-handling lambda java-8 checked-exceptions


    【解决方案1】:

    问题不在于 lambda 表达式,而在于它正在实现的接口。请记住,lambda 表达式基本上只是实现给定接口的匿名类的简写。

    在这种情况下,forEach 采用 java.util.function.Consumer<T>

    public interface Consumer<T> {
        void accept(T t);
        ...
    }
    

    请注意,accept 未被声明为抛出任何东西。这意味着它的任何实现都不会抛出任何东西;不是命名类,不是匿名类,也不是 lambda。

    【讨论】:

      【解决方案2】:

      您的read 方法似乎抛出了IOException

      IntStream.forEach 的签名是forEach(IntConsumer action),其中IntConsumer 有一个void accept(int value) 方法。在这种情况下,您的 lambda 表达式 i -&gt; someList.add(read(istream)) 相当于:

      public class IntConsumerImplementation implements IntConsumer {
         ObjectInputStream istream;
         public void accept(int i) {
            someList.add(read(istream));
         };
      }
      

      因为read 抛出了一个已检查的异常而无法编译。

      另一方面,如果函数式接口定义了 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)));
      }
      

      【讨论】:

        猜你喜欢
        • 2014-10-19
        • 1970-01-01
        • 2015-07-21
        • 2011-04-15
        • 1970-01-01
        • 2020-06-28
        • 2017-06-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多