异常介绍
# 10.1 异常介绍
异常分为编译时异常和运行时异常:
- 编译时的异常,我们可以直观的看见,可以进行立马的更改,由 Java 编译器把关,不处理(修改代码)编译时异常就不会生成 Java 程序(Java 字节码 class 文件)。
- 运行时的错误,则是编译器能力之外的事情,我们预料不到的错误,如果不更改,程序就会崩溃,例如用户输一个超越数组大小的数字来访问数组中的元素时,就会出现 ArrayIndexOutOfBoundsException 这个异常。
Java 中的异常体系,简要的如下图所示:
Java 定义了两种类型的异常:
- **Checked exception:**继承自 Exception 类的就是 Checked exception。代码需要明确的处理抛出的 Checked exception,要么用 catch 语句,要么直接用 throws 语句抛出去让调用方处理。
- **Unchecked exception:**也称 RuntimeException,它也是继承自 Exception。但所有 Runtime Exception 的子类都有个特点,就是代码不需要处理它们的异常也能通过编译,所以它们称作 Unchecked Exception。RuntimeException(运行时异常)就是不需要 try...catch... 或 throws 机制去处理的异常。
如果出现了 RuntimeException,就一定是程序员自身的问题。比如说,数组下标越界(程序应该控制不越界的下标)和访问空指针异常等等,只要你稍加留心这些异常都是在编码阶段可以避免的异常。
Java 中常见的异常及说明如下:
异常类型 | 说明 |
---|---|
Exception | 异常的根类,继承自 Throwable 类 |
RuntimeException | 运行时异常,多数 java.lang 异常的根类 |
ArithmeticException | 算术错误异常,如以零做除数 |
ArraylndexOutOfBoundException | 数组下标小于或大于实际的数组大小 |
NullPointerException | 著名的 NPE,尝试访问 null 对象成员,空指针异常 |
ClassNotFoundException | 不能加载所需的类 |
NumberFormatException | 数字转化格式异常,比如字符串到 float 型数字的转换无效 |
IOException | I/O 异常的根类 |
FileNotFoundException | 找不到文件 |
EOFException | 文件结束 |
InterruptedException | 线程中断 |
IllegalArgumentException | 方法接收到非法参数 |
ClassCastException | 类型转换异常 |
SQLException | SQL 操作数据库异常 |
在实际工作中最经常遇到的5大异常:
异常 | 示例说明 |
---|---|
ArithmeticException | int a=0; int b= 3/a; |
ClassCastException | Object x = new Integer(0); System.out.println((String)x); |
IndexOutOfBoundsException ArrayIndexOutOfBoundsException StringIndexOutOfBoundsException | int [] numbers = { 1, 2, 3 }; int sum = numbers[3]; |
IllegalArgumentException NumberFormatException | int a = Interger.parseInt("test"); |
NullPointerException | 著名的 NPE,空指针异常 |
在 Java 语言中,通过面向对象的方法来处理异常。如果在一个方法的运行过程中发生了异常,则这个方法会产生代表该异常的一个对象,并把它交给运行时的系统,运行时系统寻找相应的代码来处理这一异常。
我们把生成异常对象,并把它提交给运行时系统的过程称为拋出(throw)异常。运行时系统在方法的调用栈中查找,直到找到能够处理该类型异常的对象,这一个过程称为捕获(catch)异常。
Java 异常强制用户考虑程序的强健性和安全性。异常处理不应该用来控制程序的正常流程,而应该用来捕获程序在运行时发生的异常行为并进行相应处理,让程序能够回到正常的预期运行状态,按照编写代码时期望的路径上运行(一般而言,就是符合客户需求预期)。
编写代码处理某个方法可能出现的异常,可遵循如下三个原则:
- 在当前方法声明中使用 try catch 语句捕获异常。
- 一个方法被覆盖时,覆盖它的方法必须拋出相同的异常或异常的子类。
- 如果父类抛出多个异常,则覆盖方法必须拋出那些异常的一个子集,而不能拋出新的异常。
典型的异常处理代码:
try{
// 程序代码
}catch(异常类型1 异常的变量名1){
// 程序代码
}catch(异常类型2 异常的变量名2){
// 程序代码
}finally{
// 程序代码
}
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
另外,也可以在具体位置不处理异常(无论它是新实例化的还是刚捕获到的),通过 throw 直接抛出到上层再进行处理。这个不处理受查异常(Checked exception)的方法必须使用 throws 关键字来声明(throws 关键字放在方法签名的尾部)。
import java.io.*;
public class TestClass
{
public void doSomthing(String[] args) throws SomeException
{
//程序代码
throw new SomeException();
}
//其他方法
}
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
编辑 (opens new window)
上次更新: 2024/11/17, 16:29:23