Java中的异常处理

一、Java异常介绍

Java异常是Java提供的一种识别及响应错误的一致性机制。Java异常机制可以使程序中异常处理代码和正常业务代码分离,保证程序代码更加优雅,并提高程序健壮性。

1.Java异常框架

Java提供了丰富的异常类,这些异常类之间有严格的继承关系。Java常见的异常类继承关系如下图所示:
这里写图片描述

Throwable为顶层父类,Throwable又派生出Error类和Exception类。
Exception及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件。
Error也是Throwable的子类,它用于指示合理的应用程序不应该试图捕获的严重问题,大多数这样的错误都是异常条件。

2.检查异常与非检查异常

检查异常(checked exception):除了Error 和 RuntimeException的其它异常。也就是说Exception类本身,以及Exception的子类中除了RuntimeException之外的其它子类都属于被检查异常。它的特点是Java编译器会检查它。此类异常,要么通过throws进行声明抛出,要么通过try-catch进行捕获处理,否则不能通过编译。例如,CloneNotSupportedException就属于被检查异常。当通过clone()接口去克隆一个对象,而该对象对应的类没有实现Cloneable接口,就会抛出CloneNotSupportedException异常。

非检查异常(unckecked exception):Error和RuntimeException以及他们的子类,其特点是Java编译器不去检查它。当资源不足、约束失败、或是其它程序无法继续运行的条件发生时,就产生Error错误。RuntimeException是那些可能在Java虚拟机正常运行期间抛出的异常的超类,如除数为零时,抛出ArithmeticException异常,RuntimeException是ArithmeticException的超类。

3.运行时异常

运行时异常(Runtime Exception):即RuntimeException,其特点是Java编译器不去检查它,也就是说,当程序中可能出现这类异常时,即使没有用try catch捕获,也没有用throws抛出,还是会编译通过,如除数为零的ArithmeticException、错误的类型转换、数组越界访问和试图访问空指针等。

常见的RuntimeException

  • NullPointerException - 空指针引用异常
  • ClassCastException - 类型强制转换异常。
  • IllegalArgumentException - 传递非法参数异常。
  • ArithmeticException - 算术运算异常
  • ArrayStoreException - 向数组中存放与声明类型不兼容对象异常
  • IndexOutOfBoundsException - 下标越界异常
  • NegativeArraySizeException - 创建一个大小为负数的数组错误异常
  • NumberFormatException - 数字格式异常
  • SecurityException - 安全异常
  • UnsupportedOperationException - 不支持的操作异常

二、Java异常机制使用的关键字

Java异常机制用到的几个关键字:try、catch、finally、throw、throws。

  • try – 用于监听。将要被监听的代码(可能抛出异常的代码)放在try语句块之内,当try语句块内发生异常时,异常就被抛出。
  • catch – 用于捕获异常。catch用来捕获try语句块中发生的异常。
  • finally – 不管是否有异常产生,finally块中代码都会执行。它主要用于回收在try块里打开的物理资源(如数据库连接、网络连接和磁盘文件)。只有finally块执行完成之后,才会回来执行try或者catch块中的return或者throw语句,如果finally中使用了return或者throw等终止方法的语句,则就不会跳回执行,直接停止。
  • throw – 用于抛出异常。它可以用来抛出任意异常的,可以抛出任意 Throwable,包括自定义的异常类对象。
  • throws – 用在方法签名中,用于声明该方法可能抛出的异常。它总是出现在一个函数头中,用来标明该成员函数可能抛出的各种异常。如果方法抛出了异常,那么调用这个方法的时候就需要处理这个异常。

三、try、catch、finally中return的执行顺序

关键点

  • finally中的代码总会执行的。
  • try和catch中有return语句时,finally块仍然会执行。
  • 如果finally中没有return语句,try或catch中有return,返回值在finally执行前已经确定。
  • 如果finally中有return语句,try或catch中也有return,执行完finally中的return后直接退出。

public class TryCatchTest {
    public static void main(String args[]){
        System.out.println(test1());
        System.out.println(test2());
        System.out.println(test3());
        System.out.println(test4());
    }
    /**
     * 先执行try块中return之前(包括return语句中的表达式运算)代码,此时x为1
     * 要return的结果已经准备好了,将1存储在局部变量中
     * 再执行finally块,x此时为2
     * 最后执行try中return,将准备好的结果1取出来return;
     * @return 1
     */
    public static int test1(){
        int x = 0;
        try{
            x++;
            return x;
        }
        finally{
            x++;
        }
    }
    /**
     * 与之前类似,先执行try中的代码,执行到y=1/x时,发现异常,则try中此处之后的代码不再执行
     * 进行catch代码,为return语句,x此时为0,将需要return的结果保存起来
     * 再执行finally代码,x的值此时为1
     * 返回catch语句中return之前保存的0
     * finally{}之后的return语句不再执行
     * @return 0
     */
    public static int test2(){
        int x = 0;
        try{
            int y = 1/x;
            x++;
        }
        catch(Exception e){
            return x;
        }
        finally{
            x++;
        }
        return x;
    }
    /**
     * 首先执行try语句中的代码,其中包含return,x的值此时为1,先将其临时保存起来
     * 未发现异常,执行finally语句
     * finally代码中包含return,x的值此时为2,执行return语句后不再返回try中。
     * @return 2
     */
    public static int test3(){
        int x = 0;
        try{
            x++;
            return x;
        }
        catch(Exception e){

        }
        finally{
            x++;
            return x;
        }
    }
    /**
     * 程序执行try块中return之前代码,遇到y=1/x异常,不再执行其后的返回语句,此时x为0
     * 有异常,执行catch块中return之前代码,此时x为0,将返回结果暂时保存起来;
     * 再执行finally块,此时x为1,因为有return所以提前退出。
     * @return 1
     */
    public static int test4(){
        int x = 0;
        try{
            int y = 1/x;
            return x;
        }
        catch(Exception e){
            return x;
        }
        finally{
            x++;
            return x;
        }
    }

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值