Java要避免的前5个异常处理编码实践

330 阅读3分钟
  • 不应该捕获ThrowableError
  • 永远不应该调用Throwable.printStackTrace(...)
  • 通用异常永远不应抛出ErrorRuntimeExceptionThrowableException
  • 异常处理程序应保留原始异常
  • 不应使用System.outSystem.err来记录异常

不应该捕获ThrowableError

try {
	cl = Thread.currentThread().getContextClassLoader();	
}catch (Throwable ex) { //Non-compliant code
}

ThrowableJava中所有错误和异常的超类。错误是所有错误的超类,不应由应用程序捕获。因此,捕获Throwable本质上意味着诸如系统异常(例如,OutOfMemoryErrorStackOverFlowErrorInternalError)之类的错误也会被捕获。并且,推荐的方法是应用程序不应尝试从诸如此类的错误中恢复。因此,不应该捕获ThrowableError类。只应捕获异常及其子类

永远不应该调用Throwable.printStackTrace(...)

try {
  /* ... */
} catch(Throwable t) {
  t.printStackTrace();        // Non-Compliant
}
  • 难以检索调试日志:使用printStackTrace编写的日志写入System.err,很难在其他地方路由或过滤。相反,使用Logger,可以轻松检索日志以进行调试。
  • 违反编码最佳实践:通常,根据生产就绪应用程序中的编码指南,开发人员需要使用Logger方法记录不同级别的信息。但是,当涉及异常处理时,printStackTrace的实例通常出现在各个地方。因此,这违反了编码惯例,因此应该避免。

永远不应抛出诸如Error,RuntimeException,Throwable和Exception之类的通用异常

  • 一个人应该避免抛出Generic ExceptionsThrowableError等的主要原因是这样做会阻止类捕获预期的异常。因此,调用者无法检查异常以确定它被抛出的原因,因此无法尝试恢复。
  • 另外,捕获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.outSystem.err来记录异常

应该避免使用System.outSystem.err来记录异常的主要原因是人们可能只是松散了重要的错误消息。相反,应该使用Logging框架(如Log4JLogBack等)来记录异常。

文章有帮助你,请关注微信公众号:肆意游离 有更多精彩等着你