异常的处理

异常

1.异常的分类

image-20240104091654913

所有异常类都是 Throwable类的子类 ,它派生出两个子类, Error 类和 Exception 类。

1.Error代表的是系统级别的错误(属于严重问题),一旦出现问题,sun公司会把这些问题封装成Error对象给出来,Error是sun公司自己的,开发人员不用管。

2.Exception: 是异常,代表的是程序可能出现的问题。(程序员应该关注的问题)

  • 运行时异常(不受检异常):也称为unchecked异常,包括RuntimeException及所有子类,以及Error。对这类异常并不要求强制进行处理,运行到异常处,抛给JVM JVM 打印错误信息例如算术异常ArithmeticException等。
  • 编译时异常(受检异常):也称为checked异常,指除了不受检异常外,其他继承自Exception类的异常。对这类异常要求在代码中进行显式处理。

2.异常的处理

在程序执行过程中,如果发生了异常,程序会按照预定的处理方式对异常进行处理。处理完异常之后,程序会继续执行。如果异常没有被处理,程序将终止运行为了能让程序继续执行,有两种解决方案。

2.1 捕获异常

用try、catch、finally来捕获和处理异常。

  • try块中包含可能会抛出异常的代码。
  • catch块用于捕获并处理指定类型的异常 。
  • finally块中的代码无论是否发生异常都会被执行,通常用于释放资源或清理操作。

2.1.1 try-catch处理异常

​ try-catch语句块首先执行try语句块中的语句,这时可能会出现以下3种情况:

  1. 如果try语句块中的所有语句正常执行完毕,没有发生异常,那么catch语句块中的所有语句都将被忽略。

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

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

  4. catch语句块中可以加入用户自定义处理信息,也可以调用异常对象的方法输出异常信息,常用的方法如下:

    • void prinStackTrace() :输出异常的堆栈信息。堆栈信息包括程序运行到当前类的执行流程,它将输出从方法调用处到异常抛出处的方法调用的栈序列。

    • String getMessage() :返回异常信息描述字符串,该字符串描述了异常产生的原因,是printStackTrace() 输出信息的一部分。

2.1.2 try-catch-finally处理异常

try-catch-finally语句块组合使用时,无论try块中是否发生异常,finally语句块中的代码总能被执行。

  1. try没有发生异常,执行try块,执行finally
  2. try 发生异常 catch捕获执行catch语句 然后执行finally
  3. try 发生异常 catch没有捕获到,try剩下的代码不会被执行, 执行finally
    1. try 不能单独出现 必须和 catch/finally 两者至少其一

即使在catch语句块中存在return语句,finally语句块中的语句也会执行。发生异常时的执行顺序是,先执行catch语句块中return之前的语句,再执行finally语句块中的语句,最后执行catch语句块中的return语句退出。

finally语句块中语句不执行的唯一情况是在异常处理代码中执行了 System.exit(1) ,退出Java虚拟机。

2.1.3使用多重catch处理异常

  1. 一旦系统执行了与异常类型匹配的catch语句块,并执行其中的一条catch语句后,其后的catch语句块将被忽略,程序将继续执行紧随catch语句块的代码。
  2. 使用多重catch处理异常的时候,子类异常应该放在前面,父类异常应该放在后面,以确保正确的异常处理顺序。

2.2抛出异常

2.2.1使用throws声明抛出异常

​ 关键字throws声明某个方法可能抛出的各种异常,以通知调用者。throws可以同时声明多个异常,之间用逗号隔开。

2.2.2使用throw抛出异常

  1. 如果 throw 语句抛出的异常是 Checked 异常,则该 throw 语句要么处于 try 块里,显式捕获该异常,要么放在一个带 throws 声明抛出的方法中,即把该异常交给该方法的调用者处理;
  2. 如果 throw 语句抛出的异常是 Runtime 异常,程序既可以显式使用 try…catch来捕获并处理该异常,也可以完全不理会该异常,把该异常交给该方法调用者处理

2.2.3throw/throws的区别

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

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

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

3.自定义异常

自定义异常通常继承自 Exception 类或其子类

  • 自定义异常需要表示检查型异常(checked exception),即在方法签名中必须声明或捕捉的异常,那么继承 Exception 是合适的选择。
  • 另自定义异常是用于表示运行时异常(unchecked exception),即不需要在方法签名中声明或捕捉的异常,那么你可以选择继承 RuntimeException 类或其子类。
// 自定义异常类
class CustomException extends Exception {
    public CustomException(String message) {
        super(message);
    }
}

// 在测试类中使用自定义异常
public class CustomExceptionExample {
    public static void main(String[] args) {
        try {
            // 模拟抛出自定义异常
            throwCustomException();
        } catch (CustomException e) {
            // 捕捉并处理自定义异常
            System.out.println("Caught CustomException: " + e.getMessage());
        }
    }

    // 抛出自定义异常的方法
    private static void throwCustomException() throws CustomException {
        // 模拟条件触发自定义异常
        boolean condition = true;
        if (condition) {
            throw new CustomException("This is a custom exception message.");
        }
    }
}

4.try-with-resources

Java 7及更高版本中,引入了带资源的 try-with-resources 语句,可以更简洁地处理流的关闭。使用该语句时,你只需在 try 后面的括号中声明并初始化流,Java会在 try 块结束后自动关闭这些资源。

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class Example {

    public static void main(String[] args) {
        // 使用 try-with-resources
        try (BufferedReader reader = new BufferedReader(new FileReader("example.txt"))) {
            // 读取或写入数据的代码
        } catch (IOException e) {
            // 处理异常
            e.printStackTrace();
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值