Java 有两种异常: Checked Exception 与 Runtime Exception. 整理了一下两者的区别:
区别 | Checked Exception | Runtime Exception |
---|---|---|
基类 | java.lang.Exception | java.lang.RuntimeException |
捕获 | 强制 | 不强制 |
- Checked Exception 的基类是
Exception
; Runtime Exception 的基类是RuntimeException
(不过RuntimeException
的父类也是Exception
). - Checked Exception 要求必须捕获. 一个方法内如果抛出了 Checked Exception, 必须要么
catch
, 要么给方法声明throws
以交给上一层去处理, 如果漏写了catch
会直接通不过编译. Runtime Exception 就没这个要求, 不强制catch
或throws
, 这样对于明显不会异常的代码段就不必处理了.
各举个例子:
Runtime Exception 例子 (
IndexOutOfBoundsException
)1
2
3
4
5
6
7
8
9
10
11
12
13// ArrayList 的 get 方法, 调用了 rangeCheck 方法.
// 可以看到两个方法均没有 catch 或 声明 throws.
public E get(int index) {
rangeCheck(index);
return elementData(index);
}
// rangeCheck 可能抛出 IndexOutOfBoundsException 这一 Runtime Exception.
private void rangeCheck(int index) {
if (index >= size)
throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}Checked Exception 例子 (
FileNotFoundException
)1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20// FileInputStream 的构造函数, 声明了可能抛出 FileNotFoundException.
// 同时也可能抛出 NullPointerException, 但 NullPointerException 为
// Runtime Exception, 所以没有 throws.
public FileInputStream(File file) throws FileNotFoundException {
String name = (file != null ? file.getPath() : null);
SecurityManager security = System.getSecurityManager();
if (security != null) {
security.checkRead(name);
}
if (name == null) {
throw new NullPointerException();
}
if (file.isInvalid()) {
throw new FileNotFoundException("Invalid file path");
}
fd = new FileDescriptor();
fd.attach(this);
path = name;
open(name);
}