是否有任何特定协议用于处理公共方法中的异常?考虑这个例子。
public int someMethod()
{
try{
code that might throw an exception
}
catch(Exception e)
{
log the exception
}
}
假设此方法可能抛出ArrayIndexOutOfBoundsException。那么,在方法本身(如示例中)处理此Exception或抛出它并假设调用方法将处理异常是正确的吗?
修改 进一步扩展我的问题。 请考虑以下功能。
public int[] someMethod2()
{
try{
code that might throw an exception
}
catch(Exception e) {
log the exception
return new int[0];
}
}
如上面的示例代码所示,如果我返回一个大小为0的数组,那么调用方法将失败,并带有AraryIndexOutOfBounds异常。如果我返回null,那么调用方法将失败并出现NullPointer异常。既然,我可以修改调用方法,哪种方式更好?我应该让调用方法失败吗?或者我应该直接调用someMethod2()中的System.exit()?
是否有解释这些决定的教程? This没有给我答案。
答案 0 :(得分:2)
一般情况下,如果自己处理异常没有意义,请不要处理异常。 ArrayIndexOutOfBoundsException
通常是编程错误的标志,如果您的应用包含编程错误,则崩溃是正确和负责任的事情。
一个很大的禁忌是返回null而不是抛出异常,比如这段代码:
public Thing getThingById(long id) {
try {
ResultSet rs = queryDatabase("SELECT * FROM THING WHERE ID = " + id);
rs.next();
return new Thing(rs.get(1), rs.get(2), rs.get(3));
} catch (Exception e) {
return null;
}
}
现在,如果您从此方法获得null
,则不知道原因。身份证无效吗?数据库服务器是否已关闭?或者是queryDatabase
方法中的编程错误?
编辑哦,你永远不应该记录和重新抛出,它只会填满你的日志并让它们变得不可读。如果你重新抛出一个异常,很可能是无论代码进一步捕获它,调用链都会记录它,
答案 1 :(得分:1)
都不是。没做什么。 ArrayIndexOutOfBoundsException
表示编程错误,该错误应该根本不被捕获,或者仅在应用程序的高级别捕获。由于它是RuntimeException
的子类,因此您不必声明该方法也会抛出它。
这是例外的全部内容:您可以选择调用堆栈中的哪个位置来捕获它们,在大多数情况下,您应该不将它们捕获到正确的位置可能会被抛出。
答案 2 :(得分:0)
这取决于您是否能够以有意义的方式捕获异常,或者取决于此方法正在使用的代码合同,例如:方法的调用者期望什么等等
答案 3 :(得分:0)
这完全由你来决定。如果方法的目的是安全访问数组,则应该在该方法中处理它。但如果你做的事情完全不同,你应该重新抛出。考虑错误处理的好方法是在适当的地方处理错误。
答案 4 :(得分:0)
我通常尽可能在本地处理所有可能的事情,并且根据我的经验,绝大多数例外都是预期的和可恢复的。有时本地并不一定意味着相同的方法,并且没有什么可以为一个无法处理的方法抛出异常而感到羞耻。
此外,我通常会在程序中确定一个级别,我想要处理其他地方无法处理的异常。这可能是最高级别,也可能是当前堆栈中间可以进行部分恢复的位置。
通常,此处理只涉及记录非预期的异常并正常关闭应用程序(在非交互式应用程序的情况下)或在更多交互式应用程序中终止当前执行的线程。
处理此异常的方式主要是针对特定于应用程序的,但是您应始终在顶层开始使用catch-all来记录异常和错误,无论如何在应用程序中可能出现异常的区域编写其他处理程序可恢复的。
你永远不应该尝试从错误中恢复,但你可能仍然希望抓住它们(单独)以便正常关闭(尽管在错误的情况下这不是保证)。