我刚刚通过编写一个简单的实用程序方法解决了这样的问题,它将检查整个引起链。
/**
* Recursive method to determine whether an Exception passed is, or has a cause, that is a
* subclass or implementation of the Throwable provided.
*
* @param caught The Throwable to check
* @param isOfOrCausedBy The Throwable Class to look for
* @return true if 'caught' is of type 'isOfOrCausedBy' or has a cause that this applies to.
*/
private boolean isCausedBy(Throwable caught, Class<? extends Throwable> isOfOrCausedBy) {
if (caught == null) return false;
else if (isOfOrCausedBy.isAssignableFrom(caught.getClass())) return true;
else return isCausedBy(caught.getCause(), isOfOrCausedBy);
}
当您使用它时,您只需创建一个从最具体的异常到最不具体的 if 列表,并带有一个备用 else 子句:
try {
// Code to be executed
} catch (Exception e) {
if (isCausedBy(e, MyException.class)) {
// Handle MyException.class
} else if (isCausedBy(e, AnotherException.class)) {
// Handle AnotherException.class
} else {
throw new IllegalStateException("Error at calling service 'service'");
}
}
评论中每个请求的替代/添加
如果您想使用类似的方法来获取您要查找的类的 Exception 对象,您可以使用类似这样的方法:
private boolean getCausedByOfType(Throwable caught, Class<? extends Throwable> isOfOrCausedBy) {
if (caught == null) return null;
else if (isOfOrCausedBy.isAssignableFrom(caught.getClass())) return caught;
else return getCausedByOfType(caught.getCause(), isOfOrCausedBy);
}
除了这种方式之外,还可以使用isCausedBy()
它:
if (isCausedBy(e, MyException.class)) {
Throwable causedBy = getCausedBy(e, MyException.class);
System.err.println(causedBy.getMessage());
}
它也可以直接使用而不是isCausedBy()
,尽管这是否更具可读性可能是一个见仁见智的问题。
Throwable causedBy;
if ((causedBy = getCausedBy(e, IllegalAccessException.class)) != null) {
System.err.println(causedBy.getMessage());
}