赞
踩
1JAVA异常
异常指不期而至的各种状况,如:文件找不到、网络连接失败、内存越界等。异常是一个事件,它发生在程序运行期间,干扰了正常的指令流程。Java通过API中Throwable类的众多子类描述各种不同的异常。因而,Java异常都是对象,是Throwable子类的实例,描述了出现在一段编码中的错误条件。当条件生成时,错误将引发异常。
Java异常类层次结构图:
这里需要针对两个重要的子类说明,Exception(异常)和 Error(错误)。
Error(错误):是程序无法处理的错误,表示运行应用程序中较严重问题。
大多数错误与代码编写者执行的操作无关,而表示代码运行时 JVM(Java 虚拟机)出现的问题。例如,OutOfMemoryError、NoClassDefFoundError、StackOverFlowError。这些异常发生时,Java虚拟机(JVM)一般会选择线程终止。
Exception(异常):是程序本身可以处理的异常。
如上图,它又分为IO异常和运行时异常。我们平时最常见的就是运行时异常。比如NullPointerException、ArrayIndexOutOfBoundException等。
同时Java的异常(包括Exception和Error)又分为可查的异常(checked exceptions)和不可查的异常(unchecked exceptions)。
可查异常:简单理解为,Java编译器或者IDE会检查它,会有提示错误信息。除 了RuntimeException及其子类以外,其他的Exception类及其子类都属于可查异常,如IOException,SQLException。当程序中可能出现这类异常,要么用try-catch语句捕获它,要么用throws子句声明抛出它,否则编译不会通过。
不可查异常:反之,编译器不要求强制处置的异常就是不可查异常。包括RuntimeException与其子类和错误(Error),如NullPointerException等常见异常。这些异常一般是由程序逻辑错误引起的,程序应该从逻辑角度尽可能避免这类异常的发生。我们现在接触最多的也是现在要讲的就是这类异常处理。
2、异常处理机制
在 Java 应用程序中,异常处理机制为:抛出异常,捕捉异常。
抛出异常使用throws子句或者throw new Exception()。
捕捉异常通过try-catch语句或者try-catch-finally语句实现。
总体来说,Java规定:对于可查异常必须捕捉、或者声明抛出。允许忽略不可查的RuntimeException和Error。但是,我们提倡所有的运行时异常都要进行捕捉处理,或者抛给方法的调用者。否则出现问题,只会给用户展现一些不友好的错误代码。或者不抛出也不捕捉处理,导致方法的调用者没有任何消息,一头雾水。
下面我们以实际开发来说明两种处理机制的配合使用,达到系统的友好性和稳定性。
3.1 异常捕捉
Java中用try-catch块来捕捉可能发生的异常。以代码来说明:
这里分两种情况,一种是在catch子句中捕捉处理异常,但不向上throw异常;一种就是捕捉处理并且向上抛出异常。
解说:第二种情况向上抛出异常后,当前线程就会中断,try-catch块后面的代码就不会执行,这里平时可能需要注意。当选择向上抛出异常的时候,调用者要么用try-catch捕捉处理,要么继续向上抛出。
建议:方法是向上抛出异常还是捕捉异常进行处理,这需要根据当前方法所处的代码层级。以Java开发中典型的三层架构来讲。第一层为API层或者叫接口层,供外部调用,第二层为server层或者叫业务层,这里仍不是真正的代码处理,也只是做一些参数的封装之类的;第三层就是core层,核心层,这层主要是写代码来实现功能,比如查询数据库,调用第三方接口等。
经验:从系统架构的松耦合和实现上来讲,API层和Server层不做异常的处理工作,全部的异常处理交给core层来处理之后,返回定义好的错误代码和错误信息给上层,最后由API层将错误信息返回到显示层展示。同时在core层代码中的catch子句中打印输出的堆栈错误信息,供开发者分析错误原因。
那么什么时候需要方法抛出异常呢?
比如在core层中,有一个业务方法比较复杂,那么就需要将代码重构,抽出多个子方法来单独处理,只在主方法中一次调用抽出的子方法。那么此时,子方法中就需要进行异常抛出了,否则主方法在执行到其中的一个方法时,调用子方法遇到异常时就不知道发生什么了,线程仍然会继续调用接下来的方法,那此时系统就比较脆弱了,而且会出现各种问题。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。