java异常处理

异常概念

异常机制的本质:就是当程序出现错误,程序安全退出的机制

Java是采用面向对象的方式来处理异常的。

处理过程:

1.抛出异常:在执行一个方法时,如果发生异常,则这个方法生成代表该异常的一个对象停止当前执行路径,并把异常对象交给JRE

2.捕获异常:JRE得到该异常后,寻找相应的代码来处理该异常。JRE在方法的调用栈中查找,从生成异常的方法开始回溯,直到找到相应的异常处理代码为止。

异常分类

JDK中定义了很多异常类,这些类对应了各种各样可能出现的异常情况,所有异常对象都是派生于Throwable类的一个实例。如果内置的异常类不能够,满足需要,还可以创建自己的异常类。

Java对异常进行分类,不同类型的异常分别不同的java类表示,所有异常的类java.lang.Throwable.Throwable下面又派生了两个子类:Error和Exception,Java异常类的层次结构

1.Error(错误):java虚拟机无法解决的严重问题。如:JVM系统内部错误、资源耗尽等严重情况。比如:StackOverflowError[栈溢出]和OOM(out of memory),Error是严重错误,程序会崩溃
2.Exception:其他因编程错误或偶然的外在因素导致的一般性问题,可以使用针对性的代码进行处理。例如空指针访问,试图读取不存在的文件,网络连接中断等等,Exception分为两大类:运行时异常和编译时异常。

运行时异常

派生于Runtime的异常,如被0除、数组下标越界、空指针等,其产生比较频繁,处理麻烦。如果显示的声明或铺获将对程序可读性和运行效率影响很大。因此由系统自动检测并将它们交给缺省的异常处理程序(用户不必对其处理)。

常见的运行时异常

  • NullPointerException 空指针异常 
  • ArithmeticException 数学运算异常
  • ArrayIndexOutOfBoundsException 数组下标越界异常
  • ClassCastException 类型转换异常
  • NumberFormatException 数字格式异常

编译时异常

所有不是RuntimeException的异常,统称为CheckedException,又称为“已检查异常”,如IOException、SQLException等以及用户自定义的EXception异常,这类异常在编译时就必须做出处理,否则无法通过编译。

异常的处理方法有:try/catch 捕获,使用throws 声明异常

Throws异常捕获

①如果一个方法(中的语句执行时)可能生成某种异常,但是并不能确定如何这种异常,则此方法应显示地声明抛出异常,表明该方法将不对这些异常进行处理,而由该方法的调用者负责处理。

②在方法声明中用throws语句可以声明抛出异常的列表,throws后面的异常类型可以是方法中产生的异常类型,也可以是它的父类。

注意事项

①对于编译异常,程序中必须处理,必须try-catch或者throws

②对于运行时异常,程序中如果没有处理默认就是throws的方式处理

③子类重写父类的方法时,对抛出异常的规定:子类重写的方法,所抛出的异常类型要么和父类抛出的异常一致,要么为父类抛出的异常的类型的子类型。

④在throws过程中,如果有方法try-catch,就可以不必throws.

try-catch捕获异常

捕获异常是通过3个关键字来实现的:try-catch-finally.用try来执行一段程序,如果出现异常,系统抛出一个异常,可以通过它的类型来捕捉(catch)来处理它,最后一步是通过finally语句为异常处理提供一个统一的出口,finally所指定的代码都要执行(catch语句可有多条,finally语句最多只能一条,根据自己的需要可有可无)。

因此try-catch有了执行的输出结果的顺序问题

①try-catch 没有异常的情况

public static void main(String[] args) {
        try {
            System.out.println("try代码块开始执行");
            int  i = 0;
            System.out.println("try代码块结束");
        }catch (Exception e){
            System.out.println("执行catch代码块");
        }
    }

 输出结果

try代码块开始执行
try代码块结束

说明:当代码没有发生异常时,则不会执行catch代码块。

②try-catch出现异常的情况

 public static void main(String[] args) {
        try {
            System.out.println("try代码块开始执行");
            int  i = 1/0; //手动异常
            System.out.println("try代码块结束");
        }catch (Exception e){
            System.out.println("执行catch代码块");
        }
    }

输出结果: 

try代码块开始执行
执行catch代码块

说明:

当try代码块中有语句出现异常时则会运行catch代码块,try代码块中异常之后代码不执行。 

③try-catch-finally 没有异常的情况

 public static void main(String[] args) {
        try {
            System.out.println("try代码块开始执行");
            int  i = 1;
            System.out.println("try代码块结束");
        }catch (Exception e){
            System.out.println("执行catch代码块");
        }finally {
            System.out.println("执行finally代码块");
        }
    }

输出结果:

try代码块开始执行
try代码块结束
执行finally代码块

说明

在没有异常的情况下,先执行try代码块的内容,再执行finally代码块的内容,不执行catch代码

④try-catch-finally出现异常的情况

 public static void main(String[] args) {
        try {
            System.out.println("try代码块开始执行");
            int  i = 1/0;
            System.out.println("try代码块结束");
        }catch (Exception e){
            System.out.println("执行catch代码块");
        }finally {
            System.out.println("执行finally代码块");
        }
    }

 输出结果

try代码块开始执行
执行catch代码块
执行finally代码块

说明:

首先执行try代码块,当出现异常时,执行catch代码块,不再执行异常之后的try代码块中的内容,最终执行finally代码块。

⑤try-catch-finally 没有异常,有返回值

  public  static int tryMethod(){
        try{
            System.out.println("try执行开始");
            System.out.println("try执行结束");
            return 1;
        }catch (Exception e) {
           System.out.println("执行catch");
            return 2;
        }finally {
             System.out.println("执行finally");
            return 3;
        }
    }

代码结果:

try执行开始
try执行结束
执行finally
3

 说明:在没有异常情况下,finally的代码块执行在try代码块return语句之前执行。若finally没有return语句时,才执行try代码块中的return语句。

⑥try-catch-finally 有异常,有返回值

 public  static int tryMethod(){
        try{
            System.out.println("try执行开始");
            int i = 1/0;
            System.out.println("try执行结束");
            return 1;
        }catch (Exception e) {
            System.out.println("执行catch");
            return 2;
        }finally {
             System.out.println("执行finally");
            return 3;
        }
    }

输出结果:

try执行开始
执行catch
执行finally
3

说明:在发生异常的时候,同样的catch代码块中return语句执行之前,先执行finnally代码块,若finnally返回值,先执行finnally代码块中return语句,否则才执行catch中的return语句。

注意事项

  • 如果异常发生了,则异常发生后面的代码不会执行,直接进入到catch代码块
  • 如果异常没有发生,则顺序执行try的代码块,不会进入到catch
  • 如果希望不管是否发生异常,都执行某代码块(比如:关闭连接,释放资源等)则使用finally关键字进行处理
  • 可以有个多个catch语句,铺获不同的异常(进行不同的业务处理),要求父类异常在后,子类异常在前,如果发生异常,只会匹配一个catch。
  • 可以进行try-finally配合使用,这种用法相当于没有铺获异常,因此程序会直接崩溃掉,应用场景,就是执行一个代码,不管是否发现异常,都必须执行某个业务逻辑。

自定义异常

当程序中出现了某些“错误”,但该错误信息并没有在Throwable子类中描述,这个时候可以自己设计异常类,用于描述该错误信息。

自定义异常的步骤

①定义类:自定义异常类继承Exception或RuntimeException

②如果继承Exception属于编译异常

③如果继承RuntimeException,属于运行异常(一般来说,继承RuntimeException)

throw 和throws的区别

意义位置后面跟的东西
throws异常处理的一种方式方法声明处异常类型
throw手动生成异常对象的关键字方法体中异常对象

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值