Java异常(一)捕获异常try......catch.....finally

在Java中,凡是可能抛出异常的语句,都可以用try ... catch捕获。把可能发生异常的语句放在try { ... }中,
然后使用catch捕获对应的Exception及其子类。多catch语句可以使用多个catch语句,每个catch分别捕获对应的Exception及其子类。
JVM在捕获到异常后,会从上到下匹配catch语句,匹配到某个catch后,执行catch代码块,然后不再继续匹配。简单地说就是:多个catch语句只有一个能被执行。

例如:public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (IOException e) {
        System.out.println(e);
    } catch (NumberFormatException e) {
        System.out.println(e);
    }
}

存在多个catch的时候,catch的顺序非常重要:子类必须写在前面。

例如:public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (IOException e) {
        System.out.println("IO error");
    } catch (UnsupportedEncodingException e) { // 永远捕获不到
        System.out.println("Bad encoding");
    }
}

对于上面的代码,UnsupportedEncodingException异常是永远捕获不到的,因为它是IOException的子类。当抛出UnsupportedEncodingException异常时,会被catch (IOException e) { ... }捕获并执行。因此,正确的写法是把子类放到前面: 

public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (UnsupportedEncodingException e) {
        System.out.println("Bad encoding");
    } catch (IOException e) {
        System.out.println("IO error");
    }
}

finally语句无论是否有异常发生,如果我们都希望执行一些语句,例如清理工作,怎么写?可以把执行语句写若干遍:正常执行的放到try中,每个catch再写一遍。 

例如:public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
        System.out.println("END");
    } catch (UnsupportedEncodingException e) {
        System.out.println("Bad encoding");
        System.out.println("END");
    } catch (IOException e) {
        System.out.println("IO error");
        System.out.println("END");
    }
}

上述代码无论是否发生异常,都会执行System.out.println("END");这条语句。那么如何消除这些重复的代码?Java的try ... catch机制还提供了finally语句,finally语句块保证有无错误都会执行。上述代码可以改写如下: 

public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (UnsupportedEncodingException e) {
        System.out.println("Bad encoding");
    } catch (IOException e) {
        System.out.println("IO error");
    } finally {
        System.out.println("END");
    }

注意finally有几个特点:finally语句不是必须的,可写可不写;finally总是最后执行。如果没有发生异常,就正常执行try { ... }语句块,然后执行finally。如果发生了异常,就中断执行try { ... }语句块,然后跳转执行匹配的catch语句块,最后执行finally。可见,finally是用来保证一些代码必须执行的。某些情况下,可以没有catch,只使用try ... finally结构。将异常抛出,不捕获,例如:

public void process(String file) throws IOException {
    try {
        ...
    } finally {
        System.out.println("END");
    }

 因为方法声明了可能抛出的异常,所以可以不写catch。捕获多种异常如果某些异常的处理逻辑相同,但是异常本身不存在继承关系,那么就得编写多条catch子句: 

public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (IOException e) {
        System.out.println("Bad input");
    } catch (NumberFormatException e) {
        System.out.println("Bad input");
    } catch (Exception e) {
        System.out.println("Unknown error");
    }
}

因为处理IOException和NumberFormatException的代码是相同的,所以我们可以把它两用|合并到一起: 

public static void main(String[] args) {
    try {
        process1();
        process2();
        process3();
    } catch (IOException | NumberFormatException e) { // IOException或NumberFormatException
        System.out.println("Bad input");
    } catch (Exception e) {
        System.out.println("Unknown error");
    }

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值