JAVA异常
异常的基本概念
异常(Exception)是指程序在运行时发生的不被期望的事件,它阻止了程序按照预期正常执行。需要注意的是,编译时期出现的错误(如语法错误)通常称为编译错误,不属于异常处理的范畴。异常处理机制旨在让程序在运行时遇到错误时,能够按照预先设定的逻辑进行应对,从而尽可能恢复或优雅终止。
异常的分类
Java中的异常和错误都继承自 Throwable
类,其层次结构如下

Error (错误): 是程序无法处理的严重问题,通常与JVM本身或系统资源相关,应用程序不应尝试捕获处理。例如 OutOfMemoryError
(内存耗尽)、StackOverflowError
(栈溢出,常由无限递归引发)等
Exception (异常): 是程序本身可以并且应该处理的问题。它分为两大类:
受检异常 (Checked Exception): 指在编译时期就必须被处理的异常。如果方法可能抛出这类异常,必须在方法签名中用 throws
声明,或者用 try-catch
块进行捕获,否则代码无法通过编译。例如 IOException
(输入输出异常)、SQLException
(SQL相关异常)
非受检异常 (Unchecked Exception): 主要指 RuntimeException
及其子类。它们在编译时期不强制要求处理,通常是由程序逻辑错误引发的,应在开发阶段通过代码修正来避免。例如 NullPointerException
(空对象异常)、ArrayIndexOutOfBoundsException
(数组越界异常)、ArithmeticException
(如除以零)
如何处理异常
Java提供了 try
、catch
、finally
、throw
、throws
关键字来处理异常
1. 捕获异常 (try-catch-finally)
基本语法结构如下:
1 2 3 4 5 6 7 8 9 10
| try { } catch (ExceptionType1 e1) { } catch (ExceptionType2 e2) { } finally { }
|
示例:处理数组越界异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| public class HelloWorld { public static void main(String[] args) { try { int[] a = new int[5]; for (int i = 0; i <= 6; i++) { a[i] = i; } } catch (ArrayIndexOutOfBoundsException e) { System.out.println("捕获到数组越界异常: " + e.getMessage()); } finally { System.out.println("这段代码总是会执行。"); } System.out.println("Hello World"); } }
|
2. 声明抛出异常 (throws)
在方法签名中使用 throws
关键字,声明该方法可能抛出的异常,将异常的处理责任交给方法的调用者。这常用于受检异常(Checked Exception)。
1 2 3
| public void readFile() throws IOException { }
|
3. 主动抛出异常 (throw)
使用 throw
关键字在代码中主动抛出一个异常对象(可以是内置异常或自定义异常)。
1 2 3
| if (divisor == 0) { throw new ArithmeticException("除数不能为零"); }
|
4. try-with-resources(自动资源管理)
对于实现了 AutoCloseable
接口的资源(如 InputStream
, OutputStream
, Connection
等),强烈推荐使用 try-with-resources 语句。它可以自动关闭资源,代码更简洁,且不易出错,无需显式编写 finally
块来关闭资源
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| import java.io.*;
public class TryWithResourcesExample { public static void main(String[] args) { try (BufferedReader br = new BufferedReader(new FileReader("test.txt"))) { String line; while ((line = br.readLine()) != null) { System.out.println("Line => " + line); } } catch (IOException e) { System.out.println("读取文件时发生异常: " + e.getMessage()); } } }
|
自定义异常
当Java标准异常类无法清晰表达特定的业务逻辑错误时,可以创建自定义异常
创建自定义异常的最佳实践:
通常继承自 Exception
(创建受检异常)或 RuntimeException
(创建非受检异常)。选择取决于错误性质:是否强制调用者处理
提供多个构造方法,通常至少包括一个带详细消息(String message)的构造方法,并调用父类构造器
可以添加自定义字段(如错误码)来提供更丰富的错误信息
示例:自定义一个非受检的业务异常
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
| public class InsufficientBalanceException extends RuntimeException { private double currentBalance; private double amountRequired;
public InsufficientBalanceException(String message, double currentBalance, double amountRequired) { super(message); this.currentBalance = currentBalance; this.amountRequired = amountRequired; }
public double getCurrentBalance() { return currentBalance; }
public double getAmountRequired() { return amountRequired; }
@Override public String toString() { return super.toString() + " Current Balance: " + currentBalance + ", Amount Required: " + amountRequired; } }
public class BankAccount { private double balance;
public void withdraw(double amount) { if (amount > balance) { throw new InsufficientBalanceException("余额不足", balance, amount); } balance -= amount; } }
|