Java学习-异常

发布于:2024-10-11 ⋅ 阅读:(211) ⋅ 点赞:(0)

目录

1. 异常的概念

2. 异常继承体系

3. Java 异常的处理机制

3.1 抛出异常

3.2 捕获异常

4. Java 异常的处理原则

5. Java 常见异常以及错误

6. try-catch-finally语句块的执行

7. try-with-resources


1. 异常的概念

  • Java 异常是一个描述在代码段中发生异常的对象,当发生异常情况时,一个代表该异常的对象被创建并且在导致该异常的方法中被抛出,而该方法可以选择自己处理异常或者传递该异常。

2. 异常继承体系

Throwable 可以用来表示任何可以作为异常抛出的类,分为两种: Error 和 Exception

  • Error:通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些错误时,建议终止程序;
  • Exception:通常情况下是可以被程序处理的,捕获后可能恢复,并且在程序中应该尽可能地去处理这些异常。

    异常关系


    Java 异常分为两种:

  • 受检异常:除了 RuntimeException 及其子类以外,其他的 Exception 类及其子类都属于这种异常。
  • 非受检异常:包括 RuntimeException 及其子类和 Error。
    注意:非受检查异常为编译器不要求强制处理的异常,受检异常则是编译器要求必须处置的异常。
    Exception 这类异常分为运行时异常和非运行时异常(编译异常):
  • 运行时异常 :包括 RuntimeException 及其子类。比如 NullPointerException、IndexOutOfBoundsException。属于非受检异常,可以进行捕捉处理,也可以不处理。
  • 非运行时异常(编译异常):RuntimeExcaption 以外的 Exception。IOException、SQLException 已经自定义的异常,必须要进行处理。

3. Java 异常的处理机制

Java 异常处理机制本质上就是抛出异常和捕捉异常。

3.1 抛出异常

  • 抛出异常
    在Java中有两种抛出异常的方式,一种是throw,直接抛出异常,另一种是throws,间接抛出异常。
// 例子
    public void eat() throws Exception {
       throw new Exception();
   } 

throws exception 在方法声明中使用,表示该方法可能产生此异常,如果在方法声明处使用了throws声明异常,该方法产生异常也不必捕获,直接把异常抛出到调用该方法的地方。如果方法有调用者,那就交给调用者处理,如果调用者继续一层层抛出,那最终交给虚拟机jvm,然后程序会中断.

3.2 捕获异常

  • 捕获异常
    Java中提供了try-catch和try-catch-finally处理异常结构进行异常捕获和处理,把可能出现异常的代码放入到try语句块中,并使用catch语句块捕获异常。
// 例子1
    public void eat() {
        try {
            sleep();
        } catch (IOException e) {
             System.out.println(e.getMessage());
        }
    }
// 例子2
       public void eat() {
        try {
            sleep();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }finally {
            
        }
    }

try-catch语句块的执行流程比较简单,首先执行的是try语句块中的语句,这时可能出现以下3种情况:

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

使用try-catch-finally处理异常:

如果希望try语句块中不管是否发生异常,都执行某些代码,那么就需要在try-catch语句块中加入finally语句块,把要执行的语句放入finally语句块中 ,无论是否发生异常finally语句块中的代码总能被执行。

try-catch-finally语句块的执行流程大致分为以下两种情况:

  • 如果try语句块中所有语句正常执行,finally语句块也会被执行。catch语句块中的代码不会被执行。
  • 如果try语句块在执行过程中发生异常,无论这种异常能否被catch语句块捕获到,都将执行finally语句块中的代码。

注意:try-catch-finally结构中的try语句是必须存在的,catch、finally语句为可选,但是两者至少出现其中之一。 如果在try语句块或者catch语句块中存在return语句,finally语句块中的语句也会执行。发生异常时的执行顺序是,先执行catch语句块中return之前的语句,再执行finally语句块中的语句,最后执行catch语句块中的return语句退出。

4. Java 异常的处理原则

  • 具体明确:抛出的异常应能通过异常类名和message准确说明异常的类型和产生异常的原因
  • 提早抛出:应尽可能早地发现并抛出异常,便于精确定位问题;
  • 延迟捕获:异常的捕获和处理应尽可能延迟,让掌握更多信息的作用域来处理异常

5. Java 常见异常以及错误

异常关系

异常关系

6. try-catch-finally语句块的执行

(1) try 块:用于捕获异常。其后可接零个或多个 catch 块,如果没有 catch 块,则必须跟一个 finally 块。

(2) catch 块:用于处理try捕获到的异常。

(3) finally 块:无论是否捕获或处理异常,finally 块里的语句都会被执行。 当在 try 块或 catch 块中遇到 return 语句时,finally 语句块将在方法返回之前被执行。

在以下 4 种特殊情况下,finally 语句块不会被执行:

  • 在finally语句块中发生了异常
  • 在前面的代码中用了System.exit()退出程序。
  • 程序所在的线程死亡。
  • 关闭 CPU。

7. try-with-resources

适用范围:任何实现 java.lang.AutoCloseable 或者 java.io.Closeable 的对象。

在 try-with-resources 语句中,任何 catch 或 finally 代码块在声明的资源关闭后运行。

使用 try-catch-finally 关闭资源:

// 读取文本文件的内容
Scanner scanner = null;
try {
    scanner = new Scanner(new File("D://read.txt"));
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
} finally {
    if (scanner != null) {
        scanner.close();
    }
}

使用 try-with-resources 语句改造上面的代码:

try (Scanner scanner = new Scanner(new File("test.txt"))) {
    while (scanner.hasNext()) {
        System.out.println(scanner.nextLine());
    }
} catch (FileNotFoundException e) {
    e.printStackTrace();
}

使用 try-with-resources 语句关闭多个资源:

try (BufferedInputStream bin = new BufferedInputStream(new FileInputStream(new File("test.txt")));  // 这里采用 ";" 进行分割
     BufferedOutputStream bout = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {
    int b;
    while ((b = bin.read()) != -1) {
        bout.write(b);
    }
}
catch (IOException e) {
    e.printStackTrace();
}

网站公告

今日签到

点亮在社区的每一天
去签到