Java 抛出一长串异常vs抛出一个异常vs抛出自定义异常?
我有一个应用程序,它使用两种API方法。这两种方法都会抛出五个以上的异常。所以,如果我只添加一个抛出声明,那么它将变成一个超过10个的列表。(我的方法无法处理十个异常中的任何一个) 我曾读到,抛出一长串异常是一种糟糕的做法。此外,扔(伞)也是一种不好的做法。那么,我该怎么办Java 抛出一长串异常vs抛出一个异常vs抛出自定义异常?,java,exception-handling,Java,Exception Handling,我有一个应用程序,它使用两种API方法。这两种方法都会抛出五个以上的异常。所以,如果我只添加一个抛出声明,那么它将变成一个超过10个的列表。(我的方法无法处理十个异常中的任何一个) 我曾读到,抛出一长串异常是一种糟糕的做法。此外,扔(伞)也是一种不好的做法。那么,我该怎么办 添加try-catch块,并在catch块中记录并退出 创建自定义异常类,包装每个异常并抛出自定义异常 是否为所有异常添加抛出声明 抛出异常 添加try-catch块,并在catch块中抛出RuntimeException?
XmlWritingException
、paymentgatewayeexception
和DataAccessException
,它们根据场景包装不同的异常
甚至可以(并且更愿意)在不同的包装器中包装相同的异常。例如,如果由于通信问题导致支付失败,则可以在PaymentGatewayException
中包装IOException
,但如果在使用xml的某些i/o操作期间失败,则可以在XmlWritingException
中包装。所有这些例子都是假设性的,但你明白了
最重要的是,将原始异常设置为新异常的原因,这样它就不会丢失
更新:事实上,如果您不能期望客户端从异常中合理恢复,那么选项5是可以的。更好的是,您创建的自定义异常可以扩展
RuntimeException
。这就是spring所做的,例如,将所有与数据相关的异常包装到中。一般来说,如果您的方法无法处理异常,它应该重新抛出它们或将它们添加到抛出部分。在catch块中隐藏异常似乎是最糟糕的选择 一如既往,这要视情况而定
如果您的API名为Foo,我将创建一个名为FooAPIException的异常。确保将源异常嵌入到FooAPIException中。在记录和显示FooAPIException时,还显示源异常的stacktrace 例如:
public class FooAPIException extends Exception {
private Exception root;
public FooAPIException (Exception e) {
super(e.getMessage(),e.getErrorCode());
root = e;
}
public Exception getRoot () {
return root;
}
// Exception ================================================================
public String toString () {
StringBuffer sb = new StringBuffer();
sb.append("[");
sb.append(getErrorCode());
sb.append("][");
sb.append(getMessage());
sb.append("]\n");
sb.append("ROOT CAUSE:");
Writer write = new StringWriter();
PrintWriter pw = new PrintWriter(write);
e.printStackTrace(pw);
pw.close();
try {
write.close();
} catch (IOException ioe) {/**/}
root = write.toString();
sb.append(write);
return sb.toString();
}
}
然后包装API:
public class FooAPI {
public static method (String params) throws FooAPIException {
try {
RealFooAPI.method(params)
} catch (Exception e) {
throw new FooAPIException(e);
}
}
}
您可以使用一些自定义异常包装异常 但是,问题是,通过隐藏异常的原因(例如,它是
IOException
),可以隐藏理论上允许更高级别的代码捕获该异常并对其进行处理的信息。在这种情况下,抛出一个RuntimeException
,并不比这更好,因此您可以用RuntimeException
将它们包装起来
我仍然会保留那些您可以想象的合理的调用方希望专门捕获并声明它们,或者将它们打包成组。如果您代码的调用方可以处理一些异常,那么我会将您的方法声明为抛出它们并传递它们。如果没有希望,那么我将创建您自己的自定义异常,该异常扩展(未选中)RuntimeException,并抛出您的自定义异常以及链接到其中的实际异常 我通常会尽可能推迟退出政策的决定。退出(如果您是指退出流程)在代码中应该始终是可延迟的,这样您就可以对其进行单元测试 总的来说,我对例外情况的看法是:
如果您没有在该方法中处理异常,那么最好将它们包装到一个或多个自定义异常中并抛出它们,这样您就可以在更高级别上处理它们
您还可以创建自定义未选中(扩展RuntimeException)异常,并将抛出的异常包装到自定义运行时异常中。抛出的异常是特定系列的成员吗?e、 g.IOException只需存储原始数据,如果有人想要异常,他们可以