异常处理:其他可选方式总结

异常处理即异常发生时,程序不能正常执行下去,我们需要进行异常处理程序来解决。但我们呢?又不可能为所有可能发生的错误都进行处理,这是一件十分繁重的任务。

通常情况下:我们仅在知道如何处理的情况下才捕获异常。

实际上,异常处理为了将错误处理的代码同错误发生的地点相分离。

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);
				}
			}
	}
}

运行结果:

谢谢大家!

猜你喜欢

转载自blog.csdn.net/qq_41026809/article/details/92806851