Java 处理异常时操作列表中*所有*项的通用方法

Java 处理异常时操作列表中*所有*项的通用方法,java,exception,lambda,Java,Exception,Lambda,我尝试对列表的所有项执行一个方法,同时忽略导致异常的条目。如果引发异常,则忽略该项,并处理以下项。最后,抛出遇到的第一个异常,以警告出现了错误 基本上,这将导致相同的输出,与输入顺序无关(如果异常是由第一个或最后一个元素引发的,则所有其他元素仍将被处理) 具体情况如下: List<Input> inputs = getInputs(); List<Output> outputs = new ArrayList<>(); MyException exc = nu

我尝试对列表的所有项执行一个方法,同时忽略导致异常的条目。如果引发异常,则忽略该项,并处理以下项。最后,抛出遇到的第一个异常,以警告出现了错误

基本上,这将导致相同的输出,与输入顺序无关(如果异常是由第一个或最后一个元素引发的,则所有其他元素仍将被处理)

具体情况如下:

List<Input> inputs = getInputs();
List<Output> outputs = new ArrayList<>();
MyException exc = null;

for(Input input: inputs){
    try{
        outputs.add(handleInput(input));
    } catch(MyException e) {
        if(exc != null){
            exc = e;
        }
    }
}

if(exc != null){
    throw exc;
}
上面的代码不起作用,因为您无法捕获Java中的一般异常。有没有其他方法可以实现这一目标


我意识到抛出异常会停止对输出列表的任何访问,但是
handleInput
可能会改变其他标志,因此检查所有元素非常重要。

处理异常的一种方法是更改设计,不使用通用异常,而是使用自己的异常(例如,
IgnorableException
而不是
E extends Throwable


在您描述的情况下,有可能实现,您将被迫在
handleInput
方法和catch子句中使用从
IgnorableException
派生的异常。

解决此问题的常用方法是使
tryAll
获取指示异常类型的类型标记:

public <I, O, E extends Exception> tryAll(
    List<I> inputs,
    ExceptionFunction<I, O, E> function,
    Class<E> exceptionType)
        throws E;
public tryAll(
列出输入,
例外功能,
类异常类型)
抛出E;
然后在实现中,只需捕获一个更广泛的类型(例如
Exception
),并使用
throw exceptionType.cast(ex)
,以确保只重新抛出给定类型的异常。像Guava这样的实用程序在这里很有用

(请注意,这是类型安全的,因为从
Throwable
扩展的类型不能是泛型的,因此异常类型始终是可重新定义的。)


如果您可以将所有异常强制放到一个公共层次结构中(或者接受只处理基本类型,如
异常
),然后您可以删除
E
type参数和相应的type token参数。

这是因为您无法捕获类型参数。在
catch
块中,您必须有一个特定的类。@SchiduLuca确实这就是我建议的解决方案不起作用的原因。我想知道是否有其他方法可以实现相同的结果。为什么不能捕获所有异常
catch(异常e)
?如果您真的需要在方法中有一个特定的throw声明,那么您可以将它包装到自己的异常中,并在最后抛出它,或者…捕获所有内容,然后使用的
实例,尽管只需应用它会很慢once@Paizo不幸的是,instanceof也不能用于泛型类型我也没有编译。我不知道你把它包装成你自己的异常是什么意思,你有一些示例代码吗?
@FunctionalInterface
public interface ExceptionFunction<T, R, E extends Throwable> {

    public R apply(T t) throws E;

}
public <I, O, E extends Exception> tryAll(
    List<I> inputs,
    ExceptionFunction<I, O, E> function,
    Class<E> exceptionType)
        throws E;