第十二章 异常处理错误

java的基本理念,结构不佳的代码不能运行。

异常,java中错误报告机制。

[1]   异常一旦发生,就不允许程序按照原来的路径继续执行下去,而是转到异常处理程序。

[2]   异常参数,默认构造器和传参数的构造器。Throwable是异常类型的根类,异常的错误信息会根据异常名称相应提示。

[3]   捕获异常 try{

} catch(){

}catch(){  }//可能try块中会有多种异常,要一一捕获

[4]   java支持终止和恢复两种模型的异常处理,恢复太难实现,一般是终止模型处理,错误已经无法挽回了。

[5]   可以自定义异常类,但必须从java中的异常类继承而来。构造器可以不带参数,也可以有一个默认构造参数。

[6]   printStackTrace()方法,打印从方法调用处到异常抛出处的方法调用序列。

[7]   java.util.logging工具将异常信息记录到日志中。

[8]   异常是对象,在继承中也可以添加其他的成员变量或函数,但是通常不会关心这些。

[9]   异常说明:要么处理异常,要么在异常说明中表明该方法将产生异常。

 

12.6 捕获所有异常

[1]   可以写一个异常处理程序捕获所有异常

catch(Exception e){

  //处理

}

[2]   Exception中主要方法 getMessage() 、 printStackTrace() 、fillInStackTrace()用于程序重新抛出异常和错误时。

[3]   printStackTrace() 栈轨迹,方法的调用序列,第0个元素,即栈顶是调用序列中最后一个方法调用。

[4]   重新抛出异常,printStackTrace()显示的还是原来异常的调用栈信息,要用fillInStackTrace()

catch(Exception e){

  //处理

  throw (Exception)e. fillInStackTrace();//新异常发生地

}

[5]   异常都是通过new在堆上创建对象,所以垃圾回收器会自动把它们清理掉。

[6]   异常链,捕获一个异常之后抛出另一个异常,希望把原始异常的信息保存下来。Throwable子类构造器中,接收一个cause(表示原始异常),将原始异常传递给新异常。带有cause参数的构造器很少,如果要把其他类型的异常链接起来,应该使用initCause()方法而不是构造器。

SomeException e = new SomeException(); e.initCause(new PreviousException);

 

12.7 java标准异常

[1]   根类Throwable,分为两类:Error(编译时和系统错误)和Exception(可以被抛出的基本类型,通常程序员关心的问题)。

[2]   特例:RuntimeException,有很多继承自它的子类。它们会自动被java虚拟机抛出,不必在异常说明中列出来。如果没有捕获,RuntimeException类型的异常会穿越所有的路径直接到达main()方法,而不会被捕获;程序退出前调用printStackException。

[3]   RuntimeException 代表的是编程错误:一类是无法预料的错误(如用户输入),另一类是程序员应该在代码中检查的错误(如数组下表越界)。

 

12.8 finally进行清理

try{

}catch(Exception e){// 这里可以有0个或多个catch

}finally{ // 一定会被执行}

[1]   java异常不允许回到异常抛出点,可以讲try块放在循环中,直到达到某个条件再结束循环。

[2]   finally主要用途:把除内存(垃圾回收器来做)之外的其他资源回复到他们的初始状态。如关闭打开的文件,网络连接等。

[3]   涉及break,continue等子句时,finally也会执行。

[4]   try块中return了,finally仍可以运行。

[5]   finally子句可能造成某种情况下的异常丢失。如finally中加return等。

 

12.9 异常限制

[1]   当覆盖方法时,只能抛出在基类方法的异常说明中列出的那些异常。异常限制对构造器不起作用,可以添加任意的异常抛出。但派生类构造器的异常说明中必须包含基类构造器的异常说明

[2]   基类抛出时,导出类的方法也可以不抛出异常。或者抛出基类异常类的子类。

 

12.10 构造器

对于在构造阶段可能会抛出异常,并要求清理的类,最安全的方式是使用嵌套的try子句。

惯用原则:在创建要清理的对象之后,立即进入一个try-finally语句块。

try {

InputFile in = new InputFile("Cleanup.java");

try {

// Perform line-by-line processing here...

} catch(Exception e) {

e.printStackTrace(System.out);

} finally {

in.dispose();

}

} catch(Exception e){

System.out.println("InputFile construction failed");

}

 

12.11 异常匹配

抛出异常时,异常处理系统会按照代码书写顺序找“最近”的处理程序。

派生类的对象也可以匹配其基类的处理程序。基类的处理程序会屏蔽派生类的异常,编译器会报错。

try {

throw new Sneeze();

} catch(Sneeze s) { //Annoyance是Sneeze的基类。 如果把两个catch的顺序互换会报错。

// ...

} catch(Annoyance a) {

// ...

}

 

12.12 其他可选方式

checked Exception”使问题变得复杂,会强制你在可能还没准备好处理错误的时候被迫加上catch子句。带来的好处比麻烦多。

两种解决办法:用RuntimeException来包装“checked Exception”,RE是在运行时才抛出的异常。另一种方法,创建自己的RuntimeException子类。

              try {

                     //处理

              }catch(Exception e) {

                     // Adapt to unchecked: 转换

                     throw new RuntimeException(e);

              }

 

12.13 异常使用指南

在以下情况使用:结束程序时,为了简化程序,让类库和程序更安全。

 

总结:异常的精髓在于报告错误,恢复能力非常有限(10%)的样子。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值