《Java编程思想》之异常处理

转自http://blog.csdn.net/cannel_2020/article/details/7220200
1、
抛出异常之后

1).使用new在对象上创建异常对象

2).终止当前的执行路径

3).从当前环境中弹出对异常对象的引用

4).异常处理机制接管程序,并开始执行异常处理机制

2、异常处理理论上有两种基本模型

1).终止模型:一旦异常抛出,就表明错误无法挽回,也能回来继续执行。比较实用。

2).恢复模型:异常处理之后继续执行程序。但是可能导致“耦合”。

3、自定异常类(具有带参数的构造器)

[java]  view plain copy
  1. class SimpleException extends Exception{  
  2.    public SimpleException(){}  
  3.    public SimpleException(String msg){  
  4.       super(msg);  
  5.    }  
  6. }  
  7. public class SimpleExceptionDemo{  
  8.    public void func() throws SimpleException{  
  9.       System.out.println("Throw SimpleExceptionfrom func().");  
  10.       throw new SimpleException();  
  11.    }  
  12.    public void func1() throws SimpleException{  
  13.       System.out.println("ThrowSimpleException from func1().");  
  14.       throw new SimpleException("Originated in func1()");  
  15.    }  
  16.    public static void main(String[] args){  
  17.       SimpleExceptionDemo sed = new SimpleExceptionDemo();  
  18.       try {  
  19.         sed.func();  
  20.       } catch (SimpleException e) {  
  21.         e.printStackTrace();  
  22.       }  
  23.       try {  
  24.         sed.func1();  
  25.       } catch (SimpleException e) {  
  26.         e.printStackTrace();  
  27.       }  
  28.    }  
  29. }  

运行结果


4、异常说明:实用关键字throws,告知客户端程序员可能会抛出的异常类型。

5、在定义抽象基类和接口时,可以throws一些实际上并不抛出的异常。这样做的好处:为异常先占个位子,以后就可以抛出这种异常而不用修改已有的代码。

6、捕获所有异常(最好放在处理程序列表的末位):

[java]  view plain copy
  1. catch (Exception e) {  
  2.    System.err.println("Caught an exception");  
  3. }  

7、如果当前异常对象重新抛出,那么printStackTrace()方法显示的将是原来异常抛出点的调用栈信息,而非重新抛出点的信息。要想更新这个信息,可以调用fillInStackTrace()方法,这将返回一个Throwable对象,它是通过把当前调用栈信息填入原来那个异常对象而建立的。

8、

[java]  view plain copy
  1. public static void main(String[] args) throws Throwable{  
  2.       try{  
  3.         throw new Throwable();  
  4.       }catch(Exception e){  
  5.         System.err.println("Caught inmain()");  
  6.       }  
  7.    }  

因为Throwable是Exception的基类,所以下面程序中将不能再main()里捕获。

9、RuntimeException(或任何从它继承的异常)是一个特例,对于这种异常,编译器不需要异常说明。原因:

1).无法预料的错误。比如在你控制范围之外传递进来的null引用。

2).作为程序员,应该在代码中进行检查的错误。(比如对于ArrayIndexOutOfBoundsException,就得注意一下数组的大小了。)在一个地方发生的异常,常常会在另一个地方导致错误。

10、finally的作用:把除了内存之外的资源恢复到它们的初始状态。例如:已经打开的文件盒网络连接,在屏幕上画的图形,甚至可以是外部世界的某个开关。

11、异常丢失

[java]  view plain copy
  1. class FirstException extends Exception{  
  2.    public String toString(){  
  3.       return "The firstException.";  
  4.    }  
  5. }  
  6. class SecondException extends Exception{  
  7.    public String toString(){  
  8.       return "The secondException.";  
  9.    }  
  10. }  
  11.    
  12. public class ErrorFinally{  
  13.    void firstFunc() throws FirstException{  
  14.       throw new FirstException();  
  15.    }  
  16.    void secondFunc() throws SecondException{  
  17.       throw new SecondException();  
  18.    }  
  19.    public static void main(String[] args) throws Exception{  
  20.       ErrorFinally error = new ErrorFinally();  
  21.       try {  
  22.         error.firstFunc();  
  23.       } finally{  
  24.         error.secondFunc();  
  25.       }  
  26.    }  
  27. }  

运行结果:


    可以看到,FirstException不见了,它被finally里的SecondException取代了。

12、异常的限制:当覆盖方法的时候,只能抛出在基类方法的异常说明里列出的那些异常。这个限制很有用,因为这意味着,当基类使用的代码应用到其派生类对象的时候,一样能够工作(当然,这是面向对象的基本概念),异常也不例外。

1).派生类构造函数的异常说明必须包含基类构造器的异常说明。

2).派生类构造器不能捕获基类构造器抛出的异常。(P275第三段最后一句怎么理解??)

3).派生类的方法可以不抛出异常,即使基类的方法有抛出异常。

4).派生类的方法可以抛出继承自"基类方法所抛出异常"的异常。

请看下面例子:

[java]  view plain copy
  1. class BaseException extends Exception{}  
  2. class FuncException extends Exception{}  
  3. class OtherfuncException extends FuncException{}  
  4. class Base {  
  5.    Base() throws BaseException {  
  6.        
  7.    }  
  8.    void func() throws FuncException {  
  9.       System.out.println("Base.func()");  
  10.    }  
  11.    void otherFunc() throws FuncException {  
  12.       System.out.println("Base.otherFunc()");  
  13.    }  
  14. }  
  15. public class InheritBase extends Base{  
  16.    //派生类构造函数的异常说明必须包含基类构造器的异常说明  
  17.    public InheritBase() throws BaseException {  
  18.       super();  
  19.    }  
  20.    //派生类的方法可以不抛出异常,即使基类的方法有抛出异常。  
  21.    void func(){  
  22.       System.out.println("InheritBase.func");  
  23.    }  
  24.    //派生类的方法可以抛出继承自"基类方法所抛出异常"的异常,如下OtherfuncException继承自FuncException  
  25.    //因为异常处理程序能捕获FuncException就一定能捕获OtherfuncException。  
  26.    void otherFunc() throws OtherfuncException{  
  27.       System.out.println("InheritBase.otherFunc()");  
  28.    }  
  29.    public static void main(String[] args){  
  30.       try {  
  31.         Base ib = new InheritBase();  
  32.         ib.func();  
  33.       } catch (BaseException e) {  
  34.         System.err.println("Caught BaseException.");  
  35.       } catch (FuncException e) {  
  36.         System.err.println("Caught funcException.");  
  37.       }  
  38.    }  
  39. }  

13、把异常传给控制台

[java]  view plain copy
  1. public static void main(String[] args) throws Exception{  
  2.        
  3. }  

14、把“被检查的异常”转换为“不检查的异常”:把“被检查的异常”这种功能给屏蔽掉。

1).

[java]  view plain copy
  1. try {  
  2.          
  3. catch (BeCheckedException e) {  
  4.    throw new RuntimeException(e);  
  5. }  

这样做的好处:不用“吐下”异常(“吐下”后异常完全消失),也不必把它放到方法的异常说明里(throws),而异常链还能保证你不会丢失任何原始异常的信息。

2).你也可以不写try-catch字句和/或异常说明,直接忽略异常,让它沿着调用栈往上“冒泡”。同时,还可以用getCause()捕获并处理特定的异常,如下例子:

[java]  view plain copy
  1. class ZeroException extends Exception{}  
  2. class FirstException extends Exception{}  
  3. class secondException extends Exception{}  
  4. class SomeOtherException extends Exception{}  
  5. //把”被检查的异常“包装起来  
  6. class WrapCheckException{  
  7.    void throwRuntimeException(int type){  
  8.       try{  
  9.         switch(type){  
  10.            case 0throw new ZeroException();  
  11.            case 1throw new FirstException();  
  12.            case 2throw new secondException();  
  13.            defaultreturn;  
  14.         }  
  15.       }catch(Exception e){  
  16.         throw new RuntimeException(e);  
  17.       }  
  18.    }  
  19. }  
  20. public class TurnOffChecking{  
  21.    public static void main(String[] args){  
  22.       WrapCheckException wce = new WrapCheckException();  
  23.       wce.throwRuntimeException(3);  
  24.       for(int i = 0; i < 4; i++){  
  25.         try{  
  26.            if(i < 3)  
  27.               wce.throwRuntimeException(i);  
  28.            else  
  29.               throw new SomeOtherException();  
  30.         }catch(SomeOtherException e){  
  31.            System.out.println("SomeOtherException:" + e);  
  32.         }catch(RuntimeException e){  
  33.            try {  
  34.               //用getCause捕获特定异常  
  35.               throw e.getCause();  
  36.            } catch (ZeroException e1) {  
  37.               System.out.println("ZeroException:" + e1);  
  38.            } catch (FirstException e1) {  
  39.               System.out.println("FirstException:" + e1);  
  40.            } catch (secondException e1) {  
  41.               System.out.println("secondException:" + e1);  
  42.            } catch (Throwable e1) {  
  43.               System.out.println("Throwable:" + e1);  
  44.            }  
  45.         }  
  46.       }  
  47.    }  
  48. }  

运行结果:


1).WrapCheckException. throwRuntimeException()把不同的异常包装进了RuntimeException对象。

2).可以不用try块就可以调用throwRuntimeException(),但是,也可以使用try块捕获你想捕获的异常。

3).程序中把getCause()的结果(也就是被包装的那个原始异常)抛出来,然后用它们自己的catch子句进行处理。

 以上内容整理自《Java编程思想》,若有遗漏,请您不吝指出。

觉得自己进度有点慢,多么想一口气把这本书看完。我还有几本?17天。现在才267页。我得加速!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值