在所有内部异常中查找特定类型的自定义异常

gra*_*der 5 java java-8

我正在尝试从特定实例类型的顶级异常中递归地找到所有内部异常(getCause的)。

public class MyCustomRunTimeException extends RuntimeException {

    public MyCustomRunTimeException() {
    }

    public MyCustomRunTimeException(Exception innerException) {
        super(innerException);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我尝试过的:

和我早期的“查找”方法:

private void findAllSpecificTypeOfInnerExceptions(Exception ex)
{

            Collection<MyCustomRunTimeException> MyCustomRunTimeExceptions = Stream.iterate(ex, Throwable::getCause)
                    .filter(element ->
                            element != null
                                    && element instanceof MyCustomRunTimeException
                    )
                    .map(obj -> (MyCustomRunTimeException) obj)
                    .collect(Collectors.toList());

}
Run Code Online (Sandbox Code Playgroud)

它不起作用。:(我已经尝试了其他几件事(尚未显示)...如果我收到的任何内容都不会引发异常,则会将它们发布为“追加”到这个问题。获取NullPointers异常,以及(取决于我的调整)java.lang.reflect.InvocationTargetException异常。

这是一些可以找到1:N“匹配”的示例。

    Exception exampleOne = new MyCustomRunTimeException();

    Exception exampleTwo = new Exception(new MyCustomRunTimeException());

    Exception exampleThree =new Exception(new Exception(new MyCustomRunTimeException()));

    Exception exampleFour =new Exception(new Exception(new MyCustomRunTimeException(new ArithmeticException())));
Run Code Online (Sandbox Code Playgroud)

Mic*_*rry 3

在这种情况下,我真的认为在循环中执行递归位最简单,而不是完全使用流:

List<Throwable> exlist = new ArrayList<>();
while(ex.getCause()!=null) {
    exlist.add(ex.getCause());
    ex = ex.getCause();
}
exlist = exlist.stream().filter(e -> e instanceof MyCustomRunTimeException).collect(Collectors.toList());
Run Code Online (Sandbox Code Playgroud)

Java 9+ 中有更好的选择,如果您使用外部库,但不是真正在核心 Java 8 中(黑客确实存在,但这使得它比上面更不清楚,恕我直言,我真的不认为它是值得为此目的引入一个外部库。)

或者这个变体:

private <T extends Throwable> Collection<T> aggregateSubClassExceptions(Throwable inputEx, Class<T> type) {

    Collection<T> returnItems = new ArrayList<>();
    Throwable exc = inputEx;
    while (exc != null) {
        if (type.isInstance(exc)) {
            returnItems.add(type.cast(exc));
        }
        exc = exc.getCause();
    }

    return returnItems;
}
Run Code Online (Sandbox Code Playgroud)

此代码获取特定类型和任何子类:

    Collection<MyCustomRunTimeException> testItOutCollection;



    Exception exampleOne = new MyCustomRunTimeException();
    Exception exampleTwo = new Exception(new MyCustomRunTimeException());
    Exception exampleThree = new Exception(new Exception(new MyCustomRunTimeException()));
    Exception exampleFour = new Exception(new Exception(new MyCustomRunTimeException(new ArithmeticException())));
    MyCustomRunTimeException exampleFive = new MyCustomRunTimeException(new MySubMyCustomRunTimeException(new MyCustomRunTimeException(new ArithmeticException())));

    testItOutCollection = this.aggregateSubClassExceptions(exampleOne, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleTwo, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleThree, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleFour, MyCustomRunTimeException.class);
    testItOutCollection = this.aggregateSubClassExceptions(exampleFive, MyCustomRunTimeException.class);
Run Code Online (Sandbox Code Playgroud)