异常的捕获和处理

本文详细介绍了Java中的异常概念、分类(包括Error、Exception和其子类),常见异常类型,以及异常处理机制(try-catch,throw,throws)。还探讨了自定义异常和异常链的重要性。
摘要由CSDN通过智能技术生成

一:异常概述

1:认识异常

异常就是我们平时在编写代码的过程中产生的错误,比如说编译时报错或者是在运行时产生的一些异常,那么今天我们就一起来深就异常,它到底有哪些,是怎么分的,以及怎么去解决。

2:异常体系结构

image-20230830171722922

如图我们可以看到所有异常类都是Throwable的子类,而Throwable佩生出了两个字类,Error 类 和 Exception类

程序中常见的异常

java.lang.CloneNotSupportedException 不支持克隆操作异常,一般是被克隆的类未实现 Cloneable 接口导致
java.lang.IndexOutOfBoundsException 下标越界异常,索引值不合法
java.lang.ArrayIndexOutOfBoundsException 数组下标越界
java.lang.StringIndexOutOfBoundsException 字符串下标越界
java.lang.NullPointerException 空指针异常,对 null 进行了运算
java.lang.ClassCastException 类型转换异常
java.util.InputMismatchException 输入不匹配异常
java.lang.IllegalStateException 非法状态异常
java.lang.NumberFormatException 数字格式化异常
java.lang.ArithmeticException 算术异常
 

二:Java中的异常处理机制

1:异常处理

(1):用try,catch,finally来捕获和处理异常

try块中包含可能会抛出异常的代码。

catch块用于捕获并处理指定类型的异常

finally块中的代码无论是否发生异常,都会被执行,通常用于释放资源或者是清理操作。

(2):使用throw,throws来抛出异常。

throw关键字用于手动抛出异常对象。

throws关键字用于在方法声明中指定可能抛出的异常类型,表示该方法可能会抛出该类型的异常,由调用者来处理。

2:捕获异常

(1)使用try-catch处理异常

public static void main(String[] args) {
        try {//包含可能会出现异常的代码
            int i = 1;
            int j = 0;
            System.out.println("begin");
            int res = i / j;
            System.out.println("end");
        }catch(Exception e){
            System.out.println("caught");
            e.printStackTrace();
        }
        System.out.println("over");
    }
    
运行结果
begin
caught
over
java.lang.ArithmeticException: / by zero
    at unusual0830.Main1.main(Main1.java:15)
​

可能会出现的情况

1.如果try语句块中的所有语句正常执行完毕,没有发生异常,那么catch语句块中的所有语句都将被忽略。 2.如果try语句块在执行过程中发生异常,并且这个异常与catch语句块中声明的异常类型匹配,那么try语句块中剩下的代码都将被忽略,而相应的catch语句块将会被执行。匹配是指catch所处理的异常类型与try块所生成的异常类型完全一致或是它的父类。

3.如果try语句块在执行过程中发生异常,而抛出的异常在catch语句块中没有被声明,那么程序立即终止运行, 程序被强迫退出。

(2)使用try-catch-finally处理异常

 public static void main(String[] args) {
        try {//包含可能会出现异常的代码
            int i = 1;
            int j = 0;
            System.out.println("begin");
            int res = i / j;
            System.out.println("end");
        }catch(Exception e){
            System.out.println("caught");
            e.printStackTrace();
        }finally {
            System.out.println("finally");
        }
        System.out.println("over");
    }
    
运行结果
begin
caught
finally
over
java.lang.ArithmeticException: / by zero
    at unusual0830.Main1.main(Main1.java:15)
​
Process finished with exit code 0
​

1.如果try语句块中所有语句正常执行完毕,程序不会进入catch语句块执行,但是finally语句块会被执行。 2.如果try语句块在执行过程中发生异常,程序会进入到catch语句块捕获异常, finally语句块也会被执行。 3.try-catch-finally结构中try语句块是必须存在的,catch、finally语句块为可选,但两者至少出现其中之一。

(3)使用多重catch来处理异常。

当一段代码可能引发多种类型的异常时,可以在一个try语句块后面跟随多个catch语句块,分别处理不同类型的异常。 catch语句块的排列顺序必须是从子类到父类,最后一个一般是Exception类。这是因为在异常处理中,catch语句块会按照从上到下的顺序进行匹配,系统会检测每个catch语句块处理的异常类型,并执行第一个与异常类型匹配的catch语句块。如果将父类异常放在前面,子类异常的catch语句块将永远不会被执行,因为父类异常的catch语句块已经处理了异常。 一旦系统执行了与异常类型匹配的catch语句块,并执行其中的一条catch语句后,其后的catch语句块将被忽略,程序将继续执行紧随catch语句块的代码。 总结起来,异常处理的顺序和匹配原则非常重要。子类异常应该放在前面,父类异常应该放在后面,以确保正确 的异常处理顺序

3:抛出异常

(1)使用throws声明来抛出异常

try-catch-finally处理的是在一个方法内部发生的异常,在方法内部直接捕获并处理。如果在一个方法体内抛出了异常,并希望调用者能够及时地捕获异常,Java语言中通过关键字throws声明某个方法可能抛出的各种异常,以通知调用者。throws可以同时声明多个异常,之间用逗号隔开

public void test() throws Exception{
​
}

(2)使用throw抛出异常

除了系统自动抛出异常外,在编程过程中,有些问题是系统无法自动发现并解决的,如年龄不在正常范围之内,性别输入的不是“男”或“女”等,此时需要程序员而不是系统来自行抛出异常,把问题提交给调用者去解决。在Java语言中,可以使用throw关键字来自行抛出异常。 如果 throw 语句抛出的异常是 Checked 异常,则该 throw 语句要么处于 try 块里,显式捕获该异常,要么放在一个带 throws 声明抛出的方法中,即把该异常交给该方法的调用者处理; 如果 throw 语句抛出的异常是 Runtime 异常,则该语句无须放在 try 块里,也无须放在带 throws 声明抛出的方法中;程序既可以显式使用 try...catch来捕获并处理该异常,也可以完全不理会该异常,把该异常交给该方法调用者处理 自行抛出Runtime 异常比自行抛出Checked 异常的灵活性更好。同样,抛出 Checked 异常则可以让编译器提醒程序员必须处理该异常。

(3)throw和throws的区别

作用不同:throw用于程序员自行产生并抛出异常,throws用于声明该方法内抛出了异常

使用位置不同:throw位于方法体内部,可以作为单独的语句使用;throws必须跟在方法参数列表的后面,不能单独使用。

内容不同:throw抛出一个异常对象,只能是一个;throws后面跟异常类,可以跟多个

4:自定义异常

1.如果自定义异常类继承Excpetion,则是编译时异常。 特点:方法中抛出的是编译时异常,必须在方法上使用throws声明,强制调用者处理。 2.如果自定义异常类继承RuntimeException,则运行时异常。 特点:方法中抛出的是运行时异常,不需要在方法上

5:异常链

异常链:有时候我们会捕获一个异常后再抛出另一个异常 顾名思义就是将异常发生的原因一个传一个串起来,即把底层的异常信息传给上层

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值