Java 异常(Exceptions)

目录

1、什么是异常?

2、捕获并处理异常

try-with-resources 语句

3、通过方法抛出异常

自定义异常


1、什么是异常?

        定义:异常是在程序执行过程中发生的一种事件,它会中断程序指令的正常流程。

        当方法中发生错误时,该方法会创建一个对象并将其移交给运行时系统。该对象称为异常对象,包含有关错误的一些信息,比如错误的类型和错误发生时程序的状态等。创建异常对象并将其交给运行时系统的行为称为抛出异常

        方法抛出异常后,运行时系统会尝试寻找处理异常的方法。这些处理异常的方法可能是一个有序的方法集合,通过调用这些方法来获取错误抛出的位置。方法调用堆栈如下:

        运行时系统会在调用堆栈中搜索可以处理该异常的方法(代码块),该代码块称为异常处理程序。搜索从发生错误的方法开始,然后按照与调用方法的相反顺序遍历调用堆栈,如果找到了适当的处理程序,运行时系统会将异常传递给处理程序。如果程序没有找到能处理该异常的代码块,那么程序将终止运行

        Java 有三种类型的异常:编译时异常、运行时异常、错误(Error)。

        在 Java 中处理异常的两种方式:

  1. 使用捕获异常的 try 语句// try...catch...finally
  2. 指定一个方法可以抛出的异常。该方法必须提供一个throws子句来列出异常。

2、捕获并处理异常

try-with-resources 语句

        在关闭文件或以其他方式恢复资源时,推荐使用 try-with-resources 语句而不是finally块。try-with-resources 语句在不再需要系统资源时会自动释放系统资源。// 关闭或者恢复资源

public void writeList() throws IOException {
    try (FileWriter f = new FileWriter("OutFile.txt");
         PrintWriter out = new PrintWriter(f)) {
        for (int i = 0; i < SIZE; i++) {
            out.println("Value at: " + i + " = " + list.get(i));
        }
    }
}

        try-with-resources 语句是一个 try 语句,在该语句中可以声明一个或多个资源。资源是程序使用完后必须关闭的对象。try-with-resources 语句可以确保在语句末尾关闭每个资源。任何实现了java.lang.AutoCloseable 或 java.io.Closeable 接口的对象,都可作为 try-with-resources 的资源使用。

        注意:try-with-resources 语句可以像普通的 try 语句一样有 catch 和 finally 块。catch 或 finally 语句块会在声明的资源被关闭后运行。

不使用 try-with-resources 语句关闭资源带来的资源泄露问题

        在 Java SE 7之前,可以使用 finally 块来关闭资源。下面的例子使用 finally 块代替 try-with-resources 语句:

static String readFirstLineFromFileWithFinallyBlock(String path) throws IOException {

    FileReader fr = new FileReader(path);
    BufferedReader br = new BufferedReader(fr);
    try {
        return br.readLine();
    } finally {
        br.close(); // 此关闭方式存在资源泄露问题
        fr.close();
    }
}

        但是,上例可能存在资源泄漏问题。上边程序在完成资源使用后,除了依赖垃圾收集器(GC)回收内存资源外,还需要通过调用资源的 close 方法,将资源释放回给操作系统。但是,如果程序在GC回收资源之前没有释放资源,那么释放资源所需的信息就会丢失。该资源仍被认为操作系统正在使用,所以会出现资源泄漏的问题。

        在本例中,如果 readLine 方法抛出异常,并且 finally 块中的 br.close() 语句抛出异常,那么FileReader已经泄漏。因此,推荐使用 try-with-resources 语句而不是 finally 块来关闭程序的资源。

3、通过方法抛出异常

        在一些情况下,异常发生时,通过代码捕获异常是合适的。然而,在一些情况下,让调用堆栈上的方法去处理异常可能更加合适。例如,异常发生时,你无法预测到所有用户的需求。那么在这种情况下,就最好不捕获异常,并允许调用堆栈上的方法去处理它。// 直接抛出异常

        Throwable Class 和它的子类:

        Error Class:当 Java 虚拟机中发生动态链接故障或其他故障时,虚拟机抛出一个 Error。简单的程序通常不会捕获或抛出 Error。

        Exception Class:大多数程序抛出和捕获派生自 Exception Class 的对象。Exception 表示发生了问题,但不是严重的系统问题。我们编写的大多数程序都会抛出和捕获 Exception,而不是 Error。

自定义异常

        继承 Exception,可以实现自定义异常。

        关于运行时异常(未检查异常):

        运行时异常可以发生在程序中的任何地方,典型的运行时异常可能非常多。如果必须在每个方法声明中添加运行时异常会降低程序的清晰度。因此,编译器不要求你捕获或指定运行时异常(尽管您可以)。

        一般来说,不要抛出 RuntimeException 或创建 RuntimeException 的子类,因为你不想为指定方法可以抛出的异常而烦恼。

        下面是底线准则:如果客户端可以合理地从异常中恢复,那么将其设置为检查异常。如果客户端无法从异常中恢复,则将其设置为未检查异常。

        // 异常是 Java 中比较简单的一部分,该处只对异常做了一些简单的记录,以上一些表述摘自一些官方的介绍,供日常学习和知识梳理。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

swadian2008

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值