疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

深入讨论Java中的异常处理


 

  异常分为两类:checked & unchecked exception

  先看一下几个常见的java中的unchecked excetion(RuntimeException)

  ArithmeticException

  ClassCastException

  IndexOutOfBoundsException

  IllegalArgumentException

  NullPointerException

  上面的几种异常类型可以引申出RuntimeException的使用场景--

  RuntimeException在正常的程序执行中是不应该出现的,无论程序的运行场景是什么样的~无论在什么环境下运行~

  RuntimeException可以看做是一种错误,理论上上层程序是可以检测并避免的~~如果上层程序员不负责任,那么不好意思,下层程序就用抛出RuntimeException的方式来响应你~~~

  checked exception相比RuntimeException来说,更多的是给上层传递了一些信息,比如:

  UserNotFoundException

  PasswordErrorException

  并且强制要求上层程序一定给出在遇到checked exception的时候的处理逻辑。就是说,我们认为在遇到checked exception的时候上层程序是走到了一个相对比较少见的情形,但是这仍然是可以接受的.可以理解为一种另类的分支语句~~~

  但是如果可以使用分支语句解决的,我们还是尽量采用分支来解决而不是去使用异常,估计这一点也是C#这种语言不提供checked exception这种异常的原因之一

  对于异常处理的额外几点:

  1、系统边界处,如在WEB中与前端交互的Controller中,在为其他系统提供的接口处,都要注意捕获所有异常,然后把异常转换为约定格式的交互数据

  2、返回给前端的信息与log信息不应该一样,比如我们可以写一个Controller层的AOP处理逻辑来捕获所有的异常

  1

  public class BaseC extends Controller {

  2

  3

  protected static final Log log = LogFactory.getLog(BaseC.class);

  4

  @Catch(Throwable.class)

  5

  public static void handleThrowable(Throwable throwable) {

  6

  log.error(ExceptionUtils.getStackTrace(throwable));

  7

  renderJSON(new ReturnData(false, "Unknown Error~~mail to abc@onede4.com,3ks!", throwable.getMessage()));

  8

  }

  9

  }

  3、异常链问题:

  异常在上层抛出的时候的处理原则:如果当前类处理不了,那就继续往上抛,如果所有的类都处理不了,比如DBException,就直接给用户一个提示就好了,但是在这个异常链处理过程中,异常不应该丢失,记log,继续throw

  4、类库或者模块应该定义自己的异常基类,比如jdbc那套接口,有一个公共的异常基类:SQLException,然后再根据具体的情况抛出定制化的异常,提供尽量详细的信息,比如:

  SQLTimeoutException

  SQLFeatureNotSupportedException

  SQLInvalidAuthorizationSpecException

  5、Thinking in java的作者说:大多数时候,异常类其实只需要一个良好定义的类名~~我们在设计异常类的命名时一定要做到准确清晰~~