不处理运行时异常通常是一种好习惯。
我有这种情况:
/**boolean returns false if the method execution fails,
so that an error can be shown to user*/
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}
catch(Exception e)
{
//Log the exception and return false
return false;
}
return true;
}
因此,从Servlet调用它将获得一个布尔值。如果它是假的,我们会显示一条消息“Save not sucessful”。这样可以,还是有更好的方法呢?
答案 0 :(得分:5)
可以处理运行时异常吗?
只要你能在那时做一些聪明的事,是的。这种“永远不会捕获运行时异常”纯粹是无稽之谈。您可能也想记录它们并做其他事情。
答案 1 :(得分:5)
不处理运行时异常通常是一种好习惯。
这句话暗示了一个错误的前提:问题不是是否,而当来捕获运行时异常。
在您的代码中的某个时刻,您肯定应该拥有一个“全能”异常处理程序。这一点称为异常障碍,它在调用堆栈中足够高,可以包含一个完整的工作单元(基本上是一个数据库事务的范围)。 / p>
这应该是你的管理原则:
如果异常必须导致当前工作单元被中止(回滚),那么不会捕获该异常直到异常障碍;
如果异常仅为本地字符,其外观仅表示采用不同的路径处理请求,则执行捕获并及早处理。
请注意,上述内容并未使用无效的检查/未检查区别。大多数现代框架完全避免了检查异常,并且不遗余力地保护程序员免受从低级代码抛出的异常。
在实践中,超过90%的例外都属于第一种中止类型。这就是术语“不可恢复”的含义 - 这意味着您无法继续正在进行的操作,但服务器可以保持运行并处理所有其他请求。我看到很多人把这与“JVM即将死亡”混为一谈,但具有这种意义的例外非常罕见,通常没有特殊的处理代码。
最后,请注意,“catch-all”处理程序不仅应该捕获RuntimeExceptions
,还应该捕获Error
,因为您希望以相同的方式记录每个异常。如果让异常转义应用程序代码,则不知道它将导致什么行为。请注意,存在一些常见错误,例如StackOverflow和OutOfMemory,它们原则上会导致不可恢复的损坏,因此属于Error
层次结构,但在大多数现实案例中 除了中止当前请求之外不会造成任何损害。你肯定不想在第一眼看到这样的错误时关闭你的服务。
答案 2 :(得分:3)
不,捕捉将军Exception
会掩盖你不想捕捉的任何其他问题。更好地捕捉特定的例外情况,使意外的人更难以失踪。
答案 3 :(得分:1)
我猜你的问题有两个方面:1)处理RuntimeException
作为标题建议和2)处理通用Exception
这些是两个不同的事情。
RuntimeExcepton
的{p> The Javadoc列出了一堆子类(NullPointerException
..等)。如果仔细观察,这些只不过是编程错误,而不是在catch
块中处理它们,应该更正代码本身,以便他们这样做不会发生。
处理通用Exception
通常被称为不良做法,因为它隐藏了可能需要不同处理的特定例外。
但是在类似于你的情况下,如果有一个Servlet给方法调用,那么必须有一种优雅的方式来告诉用户在处理请求时,如果显示堆栈跟踪,应用程序会出现问题。
所以你正在做的事情可能是一种处理方式,作为一种好的做法,记录日志中的错误/异常并纠正任何RuntimeException
答案 4 :(得分:1)
如果方法执行失败,boolean返回false, 这样就可以向用户显示错误
这是抛出异常的方法的明确原因。这就是为什么异常机制首先存在的原因。最佳做法是对这些类型的情况使用异常,而不是布尔信号。
无论何时你遵循这种模式,你都会受到各种各样的影响
我强烈建议您阅读 Effective Java 中有关异常处理的部分。基本上,如果你不能在方法中对Exception做任何有意义的事情,你应该允许它向上传递堆栈。 在最糟糕的情况下,您引用的API会抛出一个通用的已检查异常,为您提供三种选择之一(编辑:更改为void
返回类型,因为布尔返回类型为no更长的任何意义 - 你成功或抛出异常)
创建自己的。
// "MyFatalException" would be a checked Exception
public void saveData() throws MyFatalException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new MyFatalException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
}
- 输入现有类型(我的偏好是针对RuntimeException的子类)
public void saveData() throws IllegalStateException{
try{
// ... do stuff that throws Exception
}catch(Exception e){
throw new IllegalStateException("Unable to save Data due to a general exception"+
" thrown by foo.bar()", e);
}
-Declare抛出一个通用的Exception并让它通过(我不推荐这个,但你会看到许多开发人员这样做)
public void saveData() throws Exception{
// no try/catch needed. Just make the call
}
答案 5 :(得分:0)
一般概念是框架或API仅在错误在代码中无法恢复的情况下才会抛出RuntimeException。例如:您的Db已关闭,或者您的服务器套接字已关闭等等。 虽然抓住这些例外也不错,但实际上是深思熟虑的是你在抓住它们后打算做什么。例如:人们更喜欢捕获数据库级别的连接问题和错误,这些问题是运行时异常子类并在其网站上显示错误页面。检查异常通常用于代码级别的情境案例,捕获它们和处理是代码应该做的事情。
答案 6 :(得分:0)
如果您尝试这样的事情,因为您不希望您的用户出现错误页面,您可以这样做,只要您在此之前发现了所有其他例外情况。
boolean saveData()
{
try
{
//Some database calls that throw only Runtime exceptions
}catch(db_Connectivity_Exception e){
//exception like credentials invalid
}catch(db_table_Exception e){
//table desc. changed
}
catch(Exception e)
{
//Log the exception and return false
//Since you are going to log your error I hope is not harmfu
return false;
}
return true;
}
这仍然不是最佳做法