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

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页。我得加速!!

转载于:https://www.cnblogs.com/myittec/archive/2012/01/30/2392767.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值