有没有更好的(java8?)方法来收集异常的"原因堆栈"?



我们的项目中有一个BaseException extends Exception,基本上所有其他异常都来自这个类。我想更改一些在运行时处理"原因堆栈"的方法。

作为起点,我编写了以下方法:

class BaseException extends Exception {
...
/**
* Helper: creates a list containing the complete "cause stack" of this exception.
* Please note: the exception on which this method is called is part of result!
*
* @return a {@link List} of all "causes" of this exception 
*/
List<Throwable> getAllCauses() {
Throwable cause = this;
List<Throwable> causes = new ArrayList<>();
while (cause != null) {
causes.add(cause);
cause = cause.getCause();
}          
return causes;
}

这完成了工作,尽管它并不完美(名称不是很好,并且也违反了单层抽象(。

但是:有没有一种"更优雅"的方式来收集这个结果?特别是考虑到直接返回Stream<Throwable>会有所帮助。

(我主要想知道是否有一个java8 lambda/习语可以在这里提供帮助(

这篇文章应该会有所帮助。特别

Stream<Throwable> causes(Throwable t){
if (t == null) return Stream.empty();
return Stream.concat(Stream.of(t), causes(t.getCause()));
}

这是我由Spliterator实现的实现,如下所示:

public static <T> Stream<T> 
iterateUntil(T seed, UnaryOperator<T> generator, Predicate<T> proceed){
return stream(new AbstractSpliterator<T>(Long.MAX_VALUE, Spliterator.ORDERED){
private T value = seed;
public boolean tryAdvance(Consumer<? super T> action){
if(!proceed.test(value)) return false;
action.accept(value);
value = generator.apply(value);
return true;
}
}, false);
}

然后,您可以按如下方式实现getCauses,并删除递归调用:

List<Throwable> getAllCauses() {
return iterateUntil(this, Throwable::getCause, Objects::nonNull)
.collect(toList());
}

使用一些枚举对我来说似乎更合适,然后像

class BaseException extends Exception {
...
Enumeration<Throwable> getCauses() {
return new Enumeration<Throwable>() {
private Throwable current = BaseException.this;
public boolean hasMoreElements() {
return current != null;
}
public Throwable nextElement() {
Throwable c = current;
current = current.getCause();
return c;
}
}
}

在 Java 8 中,您还可以使用默认方法创建一个新接口,然后在任何异常类中使用该接口(比子类化稍微好一点Exception?(。

最新更新