不应该捕获Throwable和Error类
永远不应该调用Throwable.printStackTrace(...)
通用异常永远不应抛出Error,RuntimeException,Throwable和Exception
异常处理程序应保留原始异常
不应使用System.out或System.err来记录异常
不应该捕获Throwable和Error类
try {
cl = Thread.currentThread().getContextClassLoader();
}catch (Throwable ex) { //Non-compliant code
}
Throwable是Java中所有错误和异常的超类。错误是所有错误的超类,不应由应用程序捕获。因此,捕获Throwable本质上意味着诸如系统异常(例如,OutOfMemoryError,StackOverFlowError或InternalError)之类的错误也会被捕获。并且,推荐的方法是应用程序不应尝试从诸如此类的错误中恢复。因此,不应该捕获Throwable和Error类。只应捕获异常及其子类
永远不应该调用Throwable.printStackTrace(...)
try {
/* ... */
} catch(Throwable t) {
t.printStackTrace(); // Non-Compliant
}
难以检索调试日志:使用printStackTrace编写的日志写入System.err,很难在其他地方路由或过滤。相反,使用Logger,可以轻松检索日志以进行调试。
违反编码最佳实践:通常,根据生产就绪应用程序中的编码指南,开发人员需要使用Logger方法记录不同级别的信息。但是,当涉及异常处理时,printStackTrace的实例通常出现在各个地方。因此,这违反了编码惯例,因此应该避免。
永远不应抛出诸如Error,RuntimeException,Throwable和Exception之类的通用异常
一个人应该避免抛出Generic Exceptions,Throwable,Error等的主要原因是这样做会阻止类捕获预期的异常。因此,调用者无法检查异常以确定它被抛出的原因,因此无法尝试恢复。
另外,捕获RuntimeException被认为是一种不好的做法。因此,抛出Generic Exceptions / Throwable将导致开发人员在稍后阶段捕获异常,这最终会导致进一步的代码异味。
Following is the code sample that represents this code smell:
public void foo(String bar) throws Throwable { // Non-compliant
throw new RuntimeException("My Message"); // Non-Compliant
}
// One other instance which displays throwing Exception
public void doSomething() throws Exception {...} // Non-compliant code
Instead, one would want to do something like following:
public void foo(String bar) {
throw new CustomRuntimeException("My Message"); // Compliant
}
异常处理程序应保留原始异常
先展示些坏味道的代码示例
In the code sample below, the exception is lost.
try {
/* ... */
} catch( Exception e ) {
SomeLogger.info( e.getMessage() ); // The exception is lost. Just that exception message is written; Also, context information is not logged.
}
In the code sample below, whole exception object is lost.
try {
/* ... */
} catch( Exception e ) {
SomeLogger.info( "some context message" ); // The exception is lost
}
In the code sample below, no context message is provided.
try {
/* ... */
} catch( Exception e ) {
SomeLogger.info( e ); // No context message
}
最佳实践如下
try {
/* ... */
} catch( Exception e ) {
SomeLogger.info( "some context message", e ); // Context message is there. Also, exception object is present
}
如果需要抛出异常的话 可以这样做
try {
/* ... */
} catch (Exception e) {
throw new CustomRuntimeException("context", e); // Context message is there. Also, exception object is present
}
不应使用System.out或System.err来记录异常
应该避免使用System.out或System.err来记录异常的主要原因是人们可能只是松散了重要的错误消息。相反,应该使用Logging框架(如Log4J或LogBack等)来记录异常。