异常处理即异常发生时,程序不能正常执行下去,我们需要进行异常处理程序来解决。但我们呢?又不可能为所有可能发生的错误都进行处理,这是一件十分繁重的任务。
通常情况下:我们仅在知道如何处理的情况下才捕获异常。
实际上,异常处理为了将错误处理的代码同错误发生的地点相分离。
12.12.1历史
异常处理起源于PL/1和Mesa之类的系统中,后来又出现在CLU、Smalltalk、Modula-3、Ada、Eiffel、C++、Python、Java以及后来的Ruby和C#中。
C++中异常的设计参考了CLU方式。
异常说明的思想也来自CLU。而且C++的异常说明不属于函数的类型信息。编译时唯一要检查的是异常说明是不是前后一致;比如:如果函数或方法会抛出某些异常,那么它的重载版本或者派生版本也必须抛出同样的异常。
与Java所不同的是:C++不会再编译时进行检查以确定函数或方法是不是真的抛出异常,或者异常说明是不是完整。这样的检查只发生在运行期间。如果抛出的异常与异常说明不符合,那么C++会调用标准类库的unexpected()函数。
12.12.2观点
Martin Fowler说了这样的一段话:
“总的来说,我觉得异常很不错,但是Java的”被检查异常“带来的麻烦要比好处多。”
这句话就清楚的解释了Java的弊端所在,作者认为Java的工作应该要统一其报告错误的模型,这样所有的错误都能通过异常来报告。
当然,减少编译时施加的约束能显著提高程序员的编程效率。事实上,反射和泛型就是用来补偿静态类型检查所带来的过多限制。
有这样一句至理名言分享给大家:好的程序设计语言能帮助程序员写出好程序,但无论哪种语言都避免不了程序员用它写出了坏程序。
12.12.3把异常传递给控制台
这样做的一个好处就是不必在main()中写try-catch子句了。
import java.io.FileInputStream;
public class MainException {
public static void main(String[] args) throws Exception{
//open the file:
FileInputStream file =
new FileInputStream("MainException.java");
//use the file
//close the file:
file.close();
}
}
12.12.4把“被检查的异常”转化为“不检查的异常”
当在一个普通方法里调用别的方法时,要考虑到“我不知道该怎样处理这个异常,但是也不想把它‘吞’了,或者打印一些无用的消息”。
JDK1.4的异常链提供了一种新的思路来解决这个问题:
直接把“被检查的异常”包装进RuntimeException里面,如下所示:
try{
//... to do something useful
}catch(IDontKnowWhatToDoWithThisCheckedException e){
throw new RuntimeException(e);
}
这个技巧让我们有了一种选择,我可以选择不写try-catch子句和/或异常声明,直接忽略异常,让它自己沿着调用栈往上“冒泡”。同时,还可以使用getCause()捕获并处理特定的异常,如下所示:
import java.io.FileNotFoundException;
import java.io.IOException;
class WrapCheckedException{
void throwRuntimeException(int type) {
try {
switch(type) {
case 0:throw new FileNotFoundException();
case 1:throw new IOException();
case 2:throw new RuntimeException("Where an I?");
}
}catch(Exception e) {
throw new RuntimeException(e);
}
}
}
class SomeOtherException extends Exception{}
public class TurnOffChecking {
public static void main(String[] args) {
WrapCheckedException wce = new WrapCheckedException();
wce.throwRuntimeException(3);
for(int i=0;i<4;i++)
try {
if(i<3)
wce.throwRuntimeException(i);
else
throw new SomeOtherException();
}catch(SomeOtherException e) {
System.out.println("SomeOtherException:"+e);
}catch(RuntimeException re) {
try {
throw re.getCause();
}catch(FileNotFoundException e) {
System.out.println("FileNotFoundException"+e);
}catch(IOException e) {
System.out.println("IOException"+e);
}catch(Throwable e) {
System.out.println("Throwable:"+e);
}
}
}
}
运行结果:
谢谢大家!