使用Java Lambdas时捕获/重新抛出的替代方法?

时间:2018-03-24 19:30:06

标签: java lambda exception-handling stream java-stream

我遇到过广泛使用Java8流和lambdas的项目。代码中充满了这样的块:

... some other code ... -> {
  try {
    ... some more code ...
  }
  catch(SomeException e) {
    throw new RuntimeException(e);
  }
} ... 

或者

private void someMethodWhichWillBeCalledInALambda(...) {
  try {
    ... some code ...
  }
  catch(SomeException e) {
    throw new RuntimeException(e);
  }
}

除了使用这些额外的try / catch块乱丢代码之外,我们还失去了对堆栈进行适当异常处理的能力(在使用lambdas的代码的调用者中)。

Lambdas打破了长期存在的Java最佳实践,即将异常向上传播到最近的代码块,能够有意义地处理它。我目前无法引用这一最佳实践的权威来源,也许有人可以在评论中指出它。在这些示例中,lambda中的代码太低而无法有意义地处理异常。

我的问题是,这个混乱的替代方案是什么?

为了符合SO规则,请将您的答案仅限于正常工作的代码,但我不介意评论一些更大的想法...例如可能Java语言的增强以及如何通过JCP发送提案(如果尚不存在)。

1 个答案:

答案 0 :(得分:0)

我知道这是一个古老的问题,但是我目前正在以这种方式解决。我不知道这是否是最好的方法,但它对我有用

final Set<MyException> exceptionHolder = ConcurrentHashMap.newKeySet();

    List<fooType> foos = something.stream().parallel().map(someStuff -> {
    try{     
          return foo();
    } catch (MyException e) {
          exceptionHolder.add(e);
          return null;
    }

    }).collect(Collectors.toList());

if (exceptionHolder.isEmpty()) {
          return foos;
} else {
          throw exceptionHolder.stream().findFirst().get();
}