我们详细讲解一下 Java 中的异常,包括异常的概念、分类、处理方式和常见异常,并配套练习题和答案,力求让你一看就懂!
📘 一、异常的概念
异常(Exception) 是程序运行中发生的不正常事件,会导致程序的中断或错误。
Java 使用异常机制来处理这些错误,以提高程序的健壮性和容错性。
📘 二、异常的分类
Java 的异常有两大类:
-
检查异常(Checked Exception)
- 编译时必须处理,否则无法通过编译。
- 如:
IOException
,SQLException
等。
-
运行时异常(Unchecked Exception)
- 编译时不要求必须处理,通常是程序员的错误。
- 如:
NullPointerException
,ArrayIndexOutOfBoundsException
等。
-
错误(Error)
- 系统级错误,无法通过程序处理,通常是 JVM 级别问题。
- 如:
OutOfMemoryError
,StackOverflowError
等。
📘 三、异常的继承体系
Java 中异常的继承关系如下:
Throwable
│
├── Error(错误,系统级问题,无法恢复)
│
└── Exception(异常,程序级问题,可以处理)
│
├── 运行时异常 RuntimeException
│ └── NullPointerException, ArithmeticException, etc.
│
└── 检查异常(非运行时异常)
└── IOException, SQLException, etc.
- Throwable 是所有异常和错误的父类。
- Exception 是所有可处理异常的父类。
- RuntimeException 是运行时异常的父类。
📘 四、异常的处理方式
Java 使用 try-catch-finally 语句来处理异常。
1. try-catch 结构
try {
// 可能产生异常的代码
} catch (异常类型 变量名) {
// 处理异常的代码
}
示例:
public class ExceptionDemo {
public static void main(String[] args) {
try {
int a = 10 / 0; // 这里会产生 ArithmeticException
} catch (ArithmeticException e) {
System.out.println("除数不能为零!");
}
}
}
输出:
除数不能为零!
2. try-catch-finally 结构
try {
// 可能产生异常的代码
} catch (异常类型 变量名) {
// 处理异常的代码
} finally {
// 无论是否发生异常,都会执行的代码
}
示例:
public class FinallyDemo {
public static void main(String[] args) {
try {
int[] arr = new int[2];
arr[3] = 10; // 访问越界,产生 ArrayIndexOutOfBoundsException
} catch (ArrayIndexOutOfBoundsException e) {
System.out.println("数组越界异常!");
} finally {
System.out.println("无论是否发生异常,这里都会执行。");
}
}
}
输出:
数组越界异常!
无论是否发生异常,这里都会执行。
3. throws 关键字
- 用于方法声明时,抛出异常给调用者处理。
- 通常用于检查异常。
示例:
import java.io.*;
public class ThrowsDemo {
public static void main(String[] args) throws IOException {
readFile("test.txt");
}
public static void readFile(String path) throws IOException {
FileReader fr = new FileReader(path);
fr.close();
}
}
解释:IOException
是检查异常,需要抛出或捕获处理。
4. 自定义异常
可以通过继承 Exception
或 RuntimeException
来创建自定义异常:
class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
public class CustomExceptionDemo {
public static void main(String[] args) {
try {
throw new MyException("自定义异常触发!");
} catch (MyException e) {
System.out.println(e.getMessage());
}
}
}
输出:
自定义异常触发!
📘 五、常见异常解析
异常类型 | 说明 |
---|---|
NullPointerException | 空指针异常,访问 null 对象的属性或方法 |
ArrayIndexOutOfBoundsException | 数组索引越界异常 |
ArithmeticException | 算术异常,如除零 |
ClassCastException | 类型转换异常 |
NumberFormatException | 数字格式转换异常,如将字母转为数字 |
IOException | IO 输入输出异常 |
📘 六、练习题(带答案)
1. 运行以下代码会发生什么异常?
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
System.out.println(arr[3]);
}
}
答案:ArrayIndexOutOfBoundsException
2. 使用 try-catch-finally
处理以下代码的异常:
public class Test {
public static void main(String[] args) {
String str = null;
System.out.println(str.length());
}
}
答案:
public class Test {
public static void main(String[] args) {
try {
String str = null;
System.out.println(str.length());
} catch (NullPointerException e) {
System.out.println("空指针异常!");
} finally {
System.out.println("执行完毕!");
}
}
}
3. 自定义一个异常 NegativeNumberException
,当传入负数时抛出异常。
答案:
class NegativeNumberException extends Exception {
public NegativeNumberException(String message) {
super(message);
}
}
public class Test {
public static void main(String[] args) {
try {
checkNumber(-5);
} catch (NegativeNumberException e) {
System.out.println(e.getMessage());
}
}
public static void checkNumber(int num) throws NegativeNumberException {
if (num < 0) {
throw new NegativeNumberException("不能输入负数!");
}
}
}