【问题标题】:Throwing IOException from main() in Lambda-expression [duplicate]在 Lambda 表达式中从 main() 抛出 IOException [重复]
【发布时间】:2019-04-06 12:37:33
【问题描述】:

我的任务是将我的 throws Exception 从 main()“移动”到 lambda 表达式。这意味着当 Lambda 中发生异常时,程序会使用 main 中的 throws。问题是我无法创建任何其他可以自动执行此操作的接口,因为我的老师说只使用 java.util.Function 中的接口,我一直在互联网上寻找,但大多数情况下都有“创建新界面”。

public static void main(String[] args) throws IOException {

  Function<String, List<String>> flines = (String x) -> {
      Stream<String> streamString = Files.lines(Paths.get(x)); //Should throw Exception from main if IOException

      List<String> tmp = streamString.collect(Collectors.toList());

      return tmp;

  };

【问题讨论】:

  • 不创建新接口类型的唯一方法是在 lambda 中捕获异常,然后作为未经检查的异常重新抛出(或以其他方式处理)。

标签: java function exception lambda


【解决方案1】:

您只能抛出未经检查的异常,因为Function 没有在其功能接口的签名中声明任何已检查的异常。
因此,您只能从 lambda 主体中显式抛出 RuntimeException(及其子类)实例,例如:

  Function<String, List<String>> flines = (String x) -> {
      try{
        Stream<String> streamString = Files.lines(Paths.get(x)); 
        List<String> tmp = streamString.collect(Collectors.toList());
        return tmp;
      }
      catch (IOException e){
        throw new RuntimeIOException(e); 
      }

  };

但是在main() 方法中声明throws IOException 实在是太无奈了,因为它永远不会被抛出,但是如果你在Function 客户端中捕获了运行时异常,然后你又重新抛出了IOException。但这是很多事情几乎没有。

【讨论】:

  • 我认为这是我的老师希望看到的,但是将其放入 lambda 和使用 main 中的 IOException 有什么区别?
  • 不同之处在于抛出运行时异常(它是或派生自RuntimeException)不需要显式处理(捕获或抛出),而需要处理已检查的异常。
【解决方案2】:

您可以在 lambda 表达式中捕获 IOException,将其包装在 RuntimeException 中,在 main 中捕获该异常,提取包装后的 IOException 并将其抛出:

public static void main(String[] args) throws IOException 
{
    Function<String, List<String>> flines = (String x) -> {
      List<String> tmp = null;
      try {
        Stream<String> streamString = Files.lines(Paths.get(x));
        tmp = streamString.collect(Collectors.toList());
      } catch (IOException ioEx) {
        throw new RuntimeException (ioEx);
      }
      return tmp;
    };

    try {
      List<String> lines = flines.apply ("filename.txt");
    }
    catch (RuntimeException runEx) {
      if (runEx.getCause () instanceof IOException) {
        throw (IOException) runEx.getCause ();
      }
    }
}

【讨论】:

  • 我不相信您需要努力检查原因。 OP 说“如果 IOException 应该从 main 抛出异常”- 只是传播 RuntimeException 符合该标准,因为那是 Exception
  • 是的,据我所知,这是我无法通过包装到 RuntimeException 来做到这一点的唯一方法。我想这就是我一直在寻找的。谢谢!,
猜你喜欢
  • 2020-06-28
  • 1970-01-01
  • 2014-10-19
  • 2023-03-17
  • 2019-05-02
  • 2015-04-26
  • 1970-01-01
  • 2015-10-16
相关资源
最近更新 更多