在传统的代码中,你必须包含一些代码去处理程序错误,但是这样会导致程序很难阅读。
假设有以下流程:
int readInteger() {
Read a string from the standard input;
Convert the string to an integer value;
Return the integer value;
}
以上代码只是实现了流程,但是忽视了程序中可能出现的错误:
- 输入的字符串可能无法从标准输入里读取,比如输入的可能是一个损坏的文件;
- 输入的字符不包含数字,比如输入的是
"2r"
而不是"25"
。
为了使得代码更具有鲁棒性,你必须加入一些处理潜在错误的代码:
int readInteger() {
while (true) {
read a string from the standard input;
if (read from the standard input fails) {
handle standard input error;
} else {
convert the string to an integer value;
if (the string does not cantain an integer) {
handle invalid number fromat error;
} else {
return the integer value;
}
}
}
}
但是这样写的代码阅读性很差,业务代码和异常处理代码互相夹在在一起,代码难以阅读。引入的异常处理机制可以将业务代码和异常处理代码分开,将异常集中起来处理。因此,上述代码可以改写为:
int readInteger() {
while (true) {
try {
read a string from the standard input;
convert the string to an integer value;
return the integer value;
} catch (read from the standard input failed) {
handle the standard input error;
} catch (the string does not contain an integer) {
handle invalid number format error;
}
}
}
可以看到业务代码被集中到try
代码块里,而对异常的抓取和处理则集中到了catch
代码块里。
主要需要掌握三种类型的异常:
- 检查性异常:因为用户的错误导致的异常,程序员无法预见。比如用户打开一个不存在的文件时,一个异常就发生了,此种异常在编码时不能被简单忽略。
- 运行时异常:运行时异常是可能被避免的异常。在编译时可以被忽略。
- 错误:错误不是异常,而是脱离程序员控制的问题。错误在代码中通常被忽略。例如,当栈溢出时,一个错误就发生了。它们在编译时也检查不到。