异常使用时的常见问题及注意事项
副标题[/!--empirenews.page--]
1、当子类重写父类的带有 throws声明的函数时,其throws声明的异常必须在父类异常的可控范围内——用于处理父类的throws方法的异常处理器,必须也适用于子类的这个带throws方法 。这是为了支持多态。 例如,父类方法throws 的是2个异常,子类就不能throws 3个及以上的异常。父类throws IOException,子类就必须throws IOException或者IOException的子类。 2、Java程序可以是多线程的。每一个线程都是一个独立的执行流,独立的函数调用栈。如果程序只有一个线程,那么没有被任何代码处理的异常 会导致程序终止。如果是多线程的,那么没有被任何代码处理的异常仅仅会导致异常所在的线程结束。 也就是说,Java中的异常是线程独立的,线程的问题应该由线程自己来解决,而不要委托到外部,也不会直接影响到其它线程的执行。 1、将异常直接显示在页面或客户端 将异常直接打印在客户端的例子屡见不鲜,一旦程序运行出现异常,默认情况下容器将异常堆栈信息直接打印在页面上。从客户角度来说,任何异常都没有实际意义,绝大多数的客户也根本看不懂异常信息,软件开发也要尽量避免将异常直接呈现给用户,一定要在前端展示层对异常进行封装后展示。目前绝大多数应用都是前后端分离的模式,这种直接打印异常的情况已经相对改善了很多,不过我们在编码时还是要特别注意下这个原则。 2、忽略异常 如下异常处理只是将异常输出到控制台,没有任何意义。而且这里出现了异常并没有中断程序,进而调用代码继续执行,导致更多的异常。 public void retrieveObjectById(Long id) { try { //..some code that throws SQLException } catch (SQLException ex) { /** *了解的人都知道,这里的异常打印毫无意义,仅仅是将错误堆栈输出到控制台。 * 而在 Production 环境中,需要将错误堆栈输出到日志。 * 而且这里 catch 处理之后程序继续执行,会导致进一步的问题*/
ex.printStacktrace(); } } 捕获了异常缺不进行处理,这是我们在写代码时候的大忌,可以重构成: public void retrieveObjectById(Long id) { try { //..some code that throws SQLException } catch (SQLException ex) { throw new RuntimeException("Exception in retieveObjectById”, ex); } finally { //clean up resultset, statement, connection etc } } 3、将异常包含在循环语句块中 如下代码所示,异常包含在 for 循环语句块中。 for (int i = 0; i < 100; i++) { try { } catch (XXXException e) { //.... } } 我们都知道异常处理占用系统资源。一看,大家都认为不会犯这样的错误。换个角度,类 A 中执行了一段循环,循环中调用了 B 类的方法,B 类中被调用的方法却又包含 try-catch 这样的语句块。褪去类的层次结构,代码和上面如出一辙。 4、利用 Exception 捕捉所有潜在的异常 一段方法执行过程中抛出了几个不同类型的异常,为了代码简洁,利用基类 Exception 捕捉所有潜在的异常,如下例所示: public void retrieveObjectById(Long id) { try { //...抛出 IOException 的代码调用 //...抛出 SQLException 的代码调用 } catch (Exception e) { //这里利用基类 Exception 捕捉的所有潜在的异常,如果多个层次这样捕捉,会丢失原始异常的有效信息 (编辑:湘西站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |