1.概念
在我们写代码时,除了会遇到编译错误,我们还会遇到文件不存在、网络连接失败、空指针引用等问题,为了使我们的程序能够运行下去,Java提供了异常处理机制。就是在我们的代码中可能会出现异常,但是这并不会影响到程序的运行。
在Java中我们有这些异常处理情况:
-
try-catch 块:try 块中包含可能抛出异常的代码,catch 块用于捕获并处理特定类型的异常。如果 try 块中的代码抛出异常,程序会跳转到对应的 catch 块进行异常处理,而不会导致程序崩溃。
-
throws 关键字:在方法声明中使用 throws 关键字可以声明该方法可能抛出的异常类型,将异常的处理责任交给调用该方法的代码。在调用带有 throws 关键字声明异常的方法时,调用方需要使用 try-catch 块或者继续向上层方法传递异常。
-
finally 块:finally 块中的代码无论是否发生异常都会被执行。通常用于释放资源或执行清理操作,比如关闭文件、数据库连接等。finally 块中的代码在 try-catch 块中的代码执行完毕后执行。
-
try-with-resources 语句:try-with-resources 语句用于自动关闭实现了 AutoCloseable 接口的资源,比如文件流、网络连接等。在 try-with-resources 语句中打开的资源会在 try 块结束时自动调用 close 方法进行资源释放,无需手动管理资源的关闭,避免了可能出现的资源泄露问题
2.代码示例
(1) try-catch块
我们先以处理除法,分母为零的情况为例
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner s = new Scanner(System.in);
System.out.println("输入两个数:");
int a = s.nextInt();
int b = s.nextInt();
try {
divide(a, b);
} catch (ArithmeticException e) {
System.out.println("Cannot divide by zero!");
}
}
public static void divide(int a, int b) throws ArithmeticException {
if (b == 0) {
throw new ArithmeticException("Division by zero");
}
System.out.println("Result: " + (a / b));
}
}
我们在进行除法操作时,会出现分母为零的情况,当出现这种情况时,我们就使用 throw关键字 抛出一个分母为零的异常,接收到异常信息后,执行 catch语句 打印出错误信息提示。如果我们没有异常处理,在分母为零时我们代码在运行时就会直接报错然后终止,而我们做了异常处理,它会继续执行接下来的语句。这有助于使程序在遇到异常情况下能够进行适当的异常处理而不会导致程序崩溃。
(2)finally块
import java.io.*;
public class FinallyExample {
public static void main(String[] args) {
BufferedReader br = null;
try {
br = new BufferedReader(new FileReader("example.txt"));
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (IOException e) {
System.out.println("An error occurred while reading the file: " + e.getMessage());
} finally {
try {
if (br != null) {
br.close();
}
} catch (IOException e) {
System.out.println("Error closing the file: " + e.getMessage());
}
}
}
}
在这里我们尝试读取文件中的内容,这里用 finally块去关闭文件,因为不管是否出现异常,finally块都会执行,确保了资源的正确释放。
(3)try-with-resources语句
像 if 语句,有 if- else if 这种结构,try-catch也同样有类似的语句,就是 try-with-resources语句。
public class TryWithResourcesExample {
public static void main(String[] args) {
try (BufferedReader br = new BufferedReader(new FileReader("example.txt"))) {
String line;
while ((line = br.readLine()) != null) {
System.out.println(line);
}
} catch (FileNotFoundException e) {
System.out.println("File not found: " + e.getMessage());
} catch (IOException e) {
System.out.println("An error occurred while reading the file: " + e.getMessage());
}
}
}
我们使用 try-with-resources 语句初始化 BufferedReader 对象。在 try 块结束时,会自动调用 BufferedReader 的 close 方法来关闭文件流,无需手动处理资源释放。如果在读取文件时发生异常,catch 块将捕获并处理该异常。每一个 catch块 会捕获不同的异常,进行相应的操作。
这里我介绍一下常见的异常类:
-
Checked Exception(受检异常):这些异常必须在代码中进行处理,要么通过 try-catch 块捕获和处理,要么通过 throws 关键字声明抛出。一般情况下,受检异常是程序无法控制并需要外部干预的异常情况,例如文件未找到、网络连接问题等。常见的受检异常包括:
- IOException:表示输入输出操作遇到问题时抛出的异常。
- FileNotFoundException:表示指定路径的文件未找到。
- SQLException:表示与数据库相关的异常。
-
Unchecked Exception(运行时异常):这些异常通常由程序错误或逻辑错误引起,不需要强制捕获处理,可以选择捕获处理或者让程序因异常而终止。常见的运行时异常包括:
- NullPointerException:表示尝试访问空引用时抛出的异常。
- ArithmeticException:表示数学运算错误,如除零操作。
- ArrayIndexOutOfBoundsException:表示数组索引越界异常。