在 Java 中,异常处理是处理程序运行时错误的重要机制。通过异常处理,程序可以在发生错误时优雅地处理问题,而不是直接崩溃。
异常的基本概念
-
异常(Exception) :
-
异常是程序运行过程中发生的错误事件。
-
Java 中的异常是通过类来表示的,所有异常类都继承自
java.lang.Throwable。 -
常见的异常类:
Exception:程序可以捕获并处理的异常(如IOException、SQLException)。RuntimeException:运行时异常,通常是编程错误(如NullPointerException、ArrayIndexOutOfBoundsException)。Error:严重的系统错误(如OutOfMemoryError),通常不需要捕获。
-
-
异常的层次结构:
Throwable ├── Error └── Exception ├── RuntimeException (未检查异常) └── 其他异常(检查异常)
异常处理机制
Java 使用 try-catch-finally 块来处理异常:
1. try-catch
-
try块:放置可能抛出异常的代码。 -
catch块:捕获并处理特定类型的异常。 -
语法:
try { // 可能抛出异常的代码 } catch (ExceptionType1 e1) { // 处理 ExceptionType1 类型的异常 } catch (ExceptionType2 e2) { // 处理 ExceptionType2 类型的异常 } -
示例:
public class ExceptionExample { public static void main(String[] args) { try { int result = 10 / 0; // 可能抛出 ArithmeticException } catch (ArithmeticException e) { System.out.println("捕获到算术异常: " + e.getMessage()); } } }
2. finally
-
finally块:无论是否发生异常,finally块中的代码都会执行(除非程序提前终止,如调用System.exit())。 -
语法:
try { // 可能抛出异常的代码 } catch (ExceptionType e) { // 处理异常 } finally { // 无论是否发生异常,都会执行的代码 } -
示例:
public class FinallyExample { public static void main(String[] args) { try { int[] numbers = {1, 2, 3}; System.out.println(numbers[5]); // 可能抛出 ArrayIndexOutOfBoundsException } catch (ArrayIndexOutOfBoundsException e) { System.out.println("捕获到数组越界异常: " + e.getMessage()); } finally { System.out.println("finally 块总是会执行"); } } }
3. try-with-resources
-
try-with-resources是 Java 7 引入的一种简化资源管理的机制,用于自动关闭实现了AutoCloseable接口的资源(如文件、数据库连接等)。 -
语法:
try (资源声明) { // 使用资源的代码 } catch (ExceptionType e) { // 处理异常 } -
示例:
import java.io.BufferedReader; import java.io.FileReader; import java.io.IOException; public class TryWithResourcesExample { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { String line = br.readLine(); System.out.println(line); } catch (IOException e) { System.out.println("捕获到 IO 异常: " + e.getMessage()); } } }
抛出异常
1. 使用 throw 关键字手动抛出异常
-
你可以使用
throw关键字手动抛出一个异常对象。 -
示例:
public class ThrowExample { public static void main(String[] args) { try { checkAge(15); } catch (IllegalArgumentException e) { System.out.println("捕获到异常: " + e.getMessage()); } } public static void checkAge(int age) { if (age < 18) { throw new IllegalArgumentException("年龄必须大于或等于 18"); } } }
2. 声明方法可能抛出的异常
-
使用
throws关键字声明方法可能抛出的异常。 -
语法:
public void methodName() throws ExceptionType1, ExceptionType2 { // 方法体 } -
示例:
import java.io.IOException; public class ThrowsExample { public static void main(String[] args) { try { readFile("test.txt"); } catch (IOException e) { System.out.println("捕获到 IO 异常: " + e.getMessage()); } } public static void readFile(String fileName) throws IOException { // 模拟抛出 IOException throw new IOException("文件未找到"); } }
检查异常 vs 未检查异常
-
检查异常(Checked Exception) :
- 必须显式处理(通过
try-catch或throws)。 - 例如:
IOException、SQLException。
- 必须显式处理(通过
-
未检查异常(Unchecked Exception) :
- 通常是编程错误,不需要显式处理。
- 例如:
NullPointerException、ArrayIndexOutOfBoundsException。
自定义异常
你可以创建自己的异常类,继承自 Exception 或 RuntimeException。
示例:
public class CustomException extends Exception {
public CustomException(String message) {
super(message);
}
}
public class CustomExceptionExample {
public static void main(String[] args) {
try {
validateNumber(-1);
} catch (CustomException e) {
System.out.println("捕获到自定义异常: " + e.getMessage());
}
}
public static void validateNumber(int number) throws CustomException {
if (number < 0) {
throw new CustomException("数字不能为负数");
}
}
}
总结
- 异常处理是 Java 程序健壮性的重要保障。
- 使用
try-catch捕获异常,finally块释放资源。 - 使用
try-with-resources简化资源管理。 - 合理使用
throw和throws处理和声明异常。 - 掌握检查异常和未检查异常的区别。
- 根据需要创建自定义异常类。
通过合理的异常处理,可以提高程序的可靠性和可维护性。