转自http://blog.csdn.net/cannel_2020/article/details/7220200
1、抛出异常之后
1).使用new在对象上创建异常对象
2).终止当前的执行路径
3).从当前环境中弹出对异常对象的引用
4).异常处理机制接管程序,并开始执行异常处理机制
2、异常处理理论上有两种基本模型
1).终止模型:一旦异常抛出,就表明错误无法挽回,也能回来继续执行。比较实用。
2).恢复模型:异常处理之后继续执行程序。但是可能导致“耦合”。
3、自定异常类(具有带参数的构造器)
- class SimpleException extends Exception{
- public SimpleException(){}
- public SimpleException(String msg){
- super(msg);
- }
- }
- public class SimpleExceptionDemo{
- public void func() throws SimpleException{
- System.out.println("Throw SimpleExceptionfrom func().");
- throw new SimpleException();
- }
- public void func1() throws SimpleException{
- System.out.println("ThrowSimpleException from func1().");
- throw new SimpleException("Originated in func1()");
- }
- public static void main(String[] args){
- SimpleExceptionDemo sed = new SimpleExceptionDemo();
- try {
- sed.func();
- } catch (SimpleException e) {
- e.printStackTrace();
- }
- try {
- sed.func1();
- } catch (SimpleException e) {
- e.printStackTrace();
- }
- }
- }
运行结果:
4、异常说明:实用关键字throws,告知客户端程序员可能会抛出的异常类型。
5、在定义抽象基类和接口时,可以throws一些实际上并不抛出的异常。这样做的好处:为异常先占个位子,以后就可以抛出这种异常而不用修改已有的代码。
6、捕获所有异常(最好放在处理程序列表的末位):
- catch (Exception e) {
- System.err.println("Caught an exception");
- }
7、如果当前异常对象重新抛出,那么printStackTrace()方法显示的将是原来异常抛出点的调用栈信息,而非重新抛出点的信息。要想更新这个信息,可以调用fillInStackTrace()方法,这将返回一个Throwable对象,它是通过把当前调用栈信息填入原来那个异常对象而建立的。
8、
- public static void main(String[] args) throws Throwable{
- try{
- throw new Throwable();
- }catch(Exception e){
- System.err.println("Caught inmain()");
- }
- }
因为Throwable是Exception的基类,所以下面程序中将不能再main()里捕获。
9、RuntimeException(或任何从它继承的异常)是一个特例,对于这种异常,编译器不需要异常说明。原因:
1).无法预料的错误。比如在你控制范围之外传递进来的null引用。
2).作为程序员,应该在代码中进行检查的错误。(比如对于ArrayIndexOutOfBoundsException,就得注意一下数组的大小了。)在一个地方发生的异常,常常会在另一个地方导致错误。
10、finally的作用:把除了内存之外的资源恢复到它们的初始状态。例如:已经打开的文件盒网络连接,在屏幕上画的图形,甚至可以是外部世界的某个开关。
11、异常丢失:
- class FirstException extends Exception{
- public String toString(){
- return "The firstException.";
- }
- }
- class SecondException extends Exception{
- public String toString(){
- return "The secondException.";
- }
- }
- public class ErrorFinally{
- void firstFunc() throws FirstException{
- throw new FirstException();
- }
- void secondFunc() throws SecondException{
- throw new SecondException();
- }
- public static void main(String[] args) throws Exception{
- ErrorFinally error = new ErrorFinally();
- try {
- error.firstFunc();
- } finally{
- error.secondFunc();
- }
- }
- }
运行结果:
可以看到,FirstException不见了,它被finally里的SecondException取代了。
12、异常的限制:当覆盖方法的时候,只能抛出在基类方法的异常说明里列出的那些异常。这个限制很有用,因为这意味着,当基类使用的代码应用到其派生类对象的时候,一样能够工作(当然,这是面向对象的基本概念),异常也不例外。
1).派生类构造函数的异常说明必须包含基类构造器的异常说明。
2).派生类构造器不能捕获基类构造器抛出的异常。(P275第三段最后一句怎么理解??)
3).派生类的方法可以不抛出异常,即使基类的方法有抛出异常。
4).派生类的方法可以抛出继承自"基类方法所抛出异常"的异常。
请看下面例子:
- class BaseException extends Exception{}
- class FuncException extends Exception{}
- class OtherfuncException extends FuncException{}
- class Base {
- Base() throws BaseException {
- }
- void func() throws FuncException {
- System.out.println("Base.func()");
- }
- void otherFunc() throws FuncException {
- System.out.println("Base.otherFunc()");
- }
- }
- public class InheritBase extends Base{
- //派生类构造函数的异常说明必须包含基类构造器的异常说明
- public InheritBase() throws BaseException {
- super();
- }
- //派生类的方法可以不抛出异常,即使基类的方法有抛出异常。
- void func(){
- System.out.println("InheritBase.func");
- }
- //派生类的方法可以抛出继承自"基类方法所抛出异常"的异常,如下OtherfuncException继承自FuncException
- //因为异常处理程序能捕获FuncException就一定能捕获OtherfuncException。
- void otherFunc() throws OtherfuncException{
- System.out.println("InheritBase.otherFunc()");
- }
- public static void main(String[] args){
- try {
- Base ib = new InheritBase();
- ib.func();
- } catch (BaseException e) {
- System.err.println("Caught BaseException.");
- } catch (FuncException e) {
- System.err.println("Caught funcException.");
- }
- }
- }
13、把异常传给控制台
- public static void main(String[] args) throws Exception{
- }
14、把“被检查的异常”转换为“不检查的异常”:把“被检查的异常”这种功能给屏蔽掉。
1).
- try {
- } catch (BeCheckedException e) {
- throw new RuntimeException(e);
- }
这样做的好处:不用“吐下”异常(“吐下”后异常完全消失),也不必把它放到方法的异常说明里(throws),而异常链还能保证你不会丢失任何原始异常的信息。
2).你也可以不写try-catch字句和/或异常说明,直接忽略异常,让它沿着调用栈往上“冒泡”。同时,还可以用getCause()捕获并处理特定的异常,如下例子:
- class ZeroException extends Exception{}
- class FirstException extends Exception{}
- class secondException extends Exception{}
- class SomeOtherException extends Exception{}
- //把”被检查的异常“包装起来
- class WrapCheckException{
- void throwRuntimeException(int type){
- try{
- switch(type){
- case 0: throw new ZeroException();
- case 1: throw new FirstException();
- case 2: throw new secondException();
- default: return;
- }
- }catch(Exception e){
- throw new RuntimeException(e);
- }
- }
- }
- public class TurnOffChecking{
- public static void main(String[] args){
- WrapCheckException wce = new WrapCheckException();
- 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 e){
- try {
- //用getCause捕获特定异常
- throw e.getCause();
- } catch (ZeroException e1) {
- System.out.println("ZeroException:" + e1);
- } catch (FirstException e1) {
- System.out.println("FirstException:" + e1);
- } catch (secondException e1) {
- System.out.println("secondException:" + e1);
- } catch (Throwable e1) {
- System.out.println("Throwable:" + e1);
- }
- }
- }
- }
- }
运行结果:
1).WrapCheckException. throwRuntimeException()把不同的异常包装进了RuntimeException对象。
2).可以不用try块就可以调用throwRuntimeException(),但是,也可以使用try块捕获你想捕获的异常。
3).程序中把getCause()的结果(也就是被包装的那个原始异常)抛出来,然后用它们自己的catch子句进行处理。
以上内容整理自《Java编程思想》,若有遗漏,请您不吝指出。
觉得自己进度有点慢,多么想一口气把这本书看完。我还有几本?17天。现在才267页。我得加速!!