Java异常处理

来源:互联网 发布:php详解socket select 编辑:程序博客网 时间:2024/06/07 01:11
1.异常介绍
“异常”这个词有“我对此感到意外”的意思。问题出现了,你也许不知道该如何处理,但不应该置之不理。应该停下来看看是不是有别人或者是在别的地方能够处理这个问题,只是在当前环境中还没有足够的信息来解决这个问题。
使用异常一个相当明显的好处就是能都降低错误处理代码的复杂度。异常机制使代码的阅读,编写和调试更急井井有条。如果不使用异常,必须进行特定的错误检查,并且要处理它。如果使用异常处理,就不必在方法调用处检查,因为异常机制能够捕获这个错误。
异常最重要的方面之一就是如果问题发生了,它将不允许程序继续运行,强制程序停止运行或处理问题,返回到稳定状态。

异常体系:


Throwable是所有异常的基类,它有两个子类Error和Exception。
  • Error表示系统错误,由Java系统自己使用,应用程序不应抛出和处理。
  • Exception表示在应用程序执行过程中发生的错误,子类很多。

2.异常处理
try catch finally
如果try块中有异常则会由catch捕获,可以在catch中处理。catch可以有多个,也可以一个也没有,每个catch可以处理一个特定的异常,也可以处理多个异常。
try {    int i = 5/0;    Connection conn = DriverManager.getConnection("", "", "");    conn.createStatement();} catch (ArithmeticException | SQLException e) {    e.printStackTrace();} 
finally:
finally内的代码不管有无异常发生,都会执行。具体来说:
  • 如果没有异常发生,在try内的代码执行结束后执行。
  • 如果有异常发生且被catch捕获,在catch内的代码执行结束后执行。
  • 如果有异常发生但没被捕获,则在异常被抛给上层之前执行。
catch不是必须的,可以只有try/finally,表示不捕获异常,异常自动向上传递,但finally中的代码在异常发生后也执行。
如果try或catch中有return语句,则return在finally执行完之后再执行,但是finally并不能改变其返回值。例如:
public static int test(){    int i = 1;    try{        return i;    }finally{        i = 2;    }}
结果:返回值1. 实际执行过程中,执行到try内的return语句前,返回值保存在了一个临时变量中,然后执行finally语句。最终返回临时变量的值。所以原值不会改变。
如果在finally中有return语句呢?例如:
public static int test(){    int i = 1;    try{        int j=3/0;        return i;    }finally{        return 2;    }}
结果:2. 实际返回finally中的值。try-catch中的返回值被覆盖,甚至异常也被掩盖。
对于没有垃圾回收机制和析构函数自动调用机制的语言来说,finally非常重要,无论try块中发生了什么,内存总能得到释放。当要把除内存之外的资源恢复到出事状态时,就要用finally子句。这种需要清理的资源包括:已经打开的文件或网络连接,在屏幕上画的图形,甚至可以是外部世界的每个开关。
throws & throw
throws 是方法抛出异常,例如 public void test() throws Exception { }。如果方法体重有异常并使用try-catch处理,则方法不会抛出异常。如果没有处理,则抛出方法体中的异常。如果方法体中使用throw new Exception();抛出一个新的异常,则方法抛出此异常。如果方法体中对异常进行了捕获却没有处理,且在catch中使用throw e;语句抛出异常,则方法抛出的是try中的异常。
throw是语句抛出异常。例如catch中的throw e; 方法体中的throw new Exception();
抛出异常:就是对于异常情形不能再继续下去了,无法再解决问题,所能做的就是跳出当前环 境,把问题抛给上一级。抛出异常时候有3件事情将要发生:
1. 创建一个异常对象
2. 程序被终止并从当前环境中弹出异常对象的引用。
3. 异常处理机制接管程序继续执行。

3.自定义处理
Java提供的异常体系不可能预见所有的希望加以报告的错误。不必拘泥于Java中已有的异常类型,我们可以自定义异常来表示程序中可能会遇到的特定问题。要定义自己的异常类必须从已有的异常类继承。
example:
public class MyExcption extends Exception{  private static final long serialVersionUID = 1L;  private String errorCode = "ERR";  public MyExcption(String errorCode) {    super();  }  public MyExcption(String errorCode, String message) {    super(message);    this.errorCode = errorCode;  }  public MyExcption(String errorCode, String message, Throwable cause) {    super(message, cause);    this.errorCode = errorCode;  }}
4.其他

checked 和 unchecked exception
派生于Error或者RuntimeException的异常称为unchecked异常,所有其他的异常成为checked异常,如图所示:

checked:一般是指在编译的时候需要检查的一类exception,程序必须处理或抛出。、
unchecked:是指那些在编译时不需要处理的一些异常。在java体系里,所有的Error以及RuntimeException及其子类都是unchecked异常。

异常丢失
example:
public class LostException {    void m() throws AException{        throw new AException();    }    void n() throws BException{        throw new BException();    }    public static void main(String[] args) {        try{            LostException le = new LostException();            try {                le.m();            }finally{                le.n();            }        }catch(Exception e){            System.out.println(e);        }   }}class AException extends Exception{    public String toString() {        return "exception from A";    }}class BException extends Exception{    public String toString() {        return "exception from B";    }}
输出:exception from B
从输出可以看出,AException 消失了,它被finally子句中的BException取代,这是一个严重的缺陷,异常以一种微妙的方式丢失。


原创粉丝点击