Java异常

每日一言

大部分人都不想长大,只是没办法继续当一个小孩子。

——《小林家的龙女仆》

什么是异常

在编程中,异常(Exception)是指在程序执行期间发生的,中断了正常指令流程的事件或错误情况。

异常发生的原因有很多,通常包含以下几大类:

  • 用户输入非法数据
  • 要打开的文件不存在
  • 网络连接中断

当发生这些情况时,程序就会创建一个代表该异常的对象,并将其”抛出”(throw)。如果程序没有准备好”捕获”(catch)并处理这个异常,程序的正常执行就会中断,通常会终止并显示错误信息。

检查性异常和运行时异常

检查性异常

检查性异常是指在编译时必须被处理的异常,如果代码中可能抛出检查性异常,编译器必须强制要求程序员对异常进行捕获,否则无法编译成功。

BufferedReader 实例会可能抛出检查性异常 IOException,所以我们必须捕获它。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;

public class CheckedExceptionExample {
public static void main(String[] args) {
String filePath = "example.txt"; // 假设文件路径

try {
// 尝试打开文件并读取内容
BufferedReader reader = new BufferedReader(new FileReader(filePath));
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
reader.close(); // 关闭文件
} catch (IOException e) {
// 捕获并处理 IOException
System.err.println("发生 IO 异常: " + e.getMessage());
}
}
}

运行时异常

运行时异常 (Runtime Exception)是 Java 中的一种异常类型,它在程序运行时可能发生,但编译器不会强制要求程序员显式地捕获或声明这些异常。运行时异常是 RuntimeException 类及其子类的实例。

所以在非必要时,我们可以不用管运行时异常。

捕获异常

try/catch

使用 try 和 catch 关键字可以捕获异常。try/catch 代码块放在异常可能发生的地方。

try/catch代码块中的代码称为保护代码,使用 try/catch 的语法如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
try {
// 可能会抛出异常的代码
int result = 10 / 0;
System.out.println("结果: " + result);
} catch (ArithmeticException e) {
// 针对算术异常的处理
System.err.println("发生算术异常: " + e.getMessage());
} catch (Exception e) {
// 针对其他异常的处理
System.err.println("发生其他异常: " + e.getMessage());
} finally {
// 可选,始终会执行的清理代码
System.out.println("执行完毕,释放资源");
}

Catch 语句包含要捕获异常类型的声明。当保护代码块中发生一个异常时,try 后面的 catch 块就会被检查。

如果发生的异常包含在 catch 块中,异常会被传递到该 catch 块,这和传递一个参数的方法是一样。

抛出异常

throws

throws关键字在方法签名中声明该方法中可能抛出的检查性异常,将异常的处理责任转移给调用者。

这样在该方法中,可以赞数不用处理该异常,被throws抛出的异常由上层调用者解决。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
public void readFile(String path) throws IOException, FileNotFoundException {
// 可能抛出 IOException 或 FileNotFoundException 的代码
FileReader file = new FileReader(path);
BufferedReader reader = new BufferedReader(file);
String line = reader.readLine();
// ...
}

// 调用方必须处理这些异常
public void processFile() {
try {
readFile("example.txt");
} catch (IOException e) {
System.err.println("文件读取错误: " + e.getMessage());
}
}

throw

throw关键字用于在代码中手动抛出一个异常,以告知调用者当前代码的执行状态。

1
2
3
4
5
6
7
8
9
10
public void validateAge(int age) {
if (age < 0) {
throw new IllegalArgumentException("年龄不能为负数");
}
if (age > 150) {
throw new IllegalArgumentException("年龄不合理");
}
// 正常处理逻辑
System.out.println("年龄验证通过");
}

java 内置异常

非检查性异常 :

异常 描述
ArithmeticException 当出现异常的运算条件时,抛出此异常。例如,一个整数”除以零”时,抛出此类的一个实例。
ArrayIndexOutOfBoundsException 用非法索引访问数组时抛出的异常。如果索引为负或大于等于数组大小,则该索引为非法索引。
ArrayStoreException 试图将错误类型的对象存储到一个对象数组时抛出的异常。
ClassCastException 当试图将对象强制转换为不是实例的子类时,抛出该异常。
IllegalArgumentException 抛出的异常表明向方法传递了一个不合法或不正确的参数。
IllegalMonitorStateException 抛出的异常表明某一线程已经试图等待对象的监视器,或者试图通知其他正在等待对象的监视器而本身没有指定监视器的线程。
IllegalStateException 在非法或不适当的时间调用方法时产生的信号。换句话说,即 Java 环境或 Java 应用程序没有处于请求操作所要求的适当状态下。
IllegalThreadStateException 线程没有处于请求操作所要求的适当状态时抛出的异常。
IndexOutOfBoundsException 指示某排序索引(例如对数组、字符串或向量的排序)超出范围时抛出。
NegativeArraySizeException 如果应用程序试图创建大小为负的数组,则抛出该异常。
NullPointerException 当应用程序试图在需要对象的地方使用 null 时,抛出该异常
NumberFormatException 当应用程序试图将字符串转换成一种数值类型,但该字符串不能转换为适当格式时,抛出该异常。
SecurityException 由安全管理器抛出的异常,指示存在安全侵犯。
StringIndexOutOfBoundsException 此异常由 String 方法抛出,指示索引或者为负,或者超出字符串的大小。

检查性异常:

异常 描述
ClassNotFoundException 应用程序试图加载类时,找不到相应的类,抛出该异常。
CloneNotSupportedException 当调用 Object 类中的 clone 方法克隆对象,但该对象的类无法实现 Cloneable 接口时,抛出该异常。
IllegalAccessException 拒绝访问一个类的时候,抛出该异常。
InstantiationException 当试图使用 Class 类中的 newInstance 方法创建一个类的实例,而指定的类对象因为是一个接口或是一个抽象类而无法实例化时,抛出该异常。
InterruptedException 一个线程被另一个线程中断,抛出该异常。
NoSuchFieldException 请求的变量不存在
NoSuchMethodException 请求的方法不存在

异常类的主要方法:

序号 方法及说明
1 public String getMessage()``返回关于发生的异常的详细信息。这个消息在Throwable 类的构造函数中初始化了。
2 public Throwable getCause()``返回一个 Throwable 对象代表异常原因。
3 public String toString()``返回此 Throwable 的简短描述。
4 public void printStackTrace()``将此 Throwable 及其回溯打印到标准错误流。
5 public StackTraceElement [] getStackTrace()``返回一个包含堆栈层次的数组。下标为0的元素代表栈顶,最后一个元素代表方法调用堆栈的栈底。
6 public Throwable fillInStackTrace()``用当前的调用栈层次填充Throwable 对象栈层次,添加到栈层次任何先前信息中。

声明自定义异常

在Java中我们可以自定义异常类:

  • 如果希望写一个检查性异常类,则需要继承Exception 类
  • 如果希望写一个运行时异常类,那么需要继承RuntimeException类

可以像下面这样定义自己的异常类:

1
2
class MyException extends Exception{
}

一个异常类和其它任何类一样,包含有变量和方法。


Java异常
http://blog.ulna520.com/2025/04/21/Java异常_20250421_162012/
Veröffentlicht am
April 21, 2025
Urheberrechtshinweis