异常与错误处理

日期:2015-10-23点击次数:16606

        Java的基本原理是:结构不佳的代码将不能运行与C++类似,捕获错误最佳时期是在编译期间,也就是在试图运行程序之前。但是,并非所有的错误都能在编译期间找到。有些问题必须在运行期间解决,这样必须让错误源通过某种方式向接收者传递一些适当的信息,以便接收者能够正确的处理该问题。
       在c++和其他早期的语言中,可通过几种手段来达到这个目的。并且他们通常作为一种规定建立起来的,而不是程序设计语言的一部分。典型的做法是标志位。这种做法有两个弊端。其一是人的麻痹情绪和惰性,往往不会检查是否出错;其二是每一次调用方法时都得进行全面、细致的错误检查,这样代码的可读性非常差,不易于维护,而且程序也不健壮。
       解决办法是用强制规定的形式来消除错误处理过程当中随心所欲的因素。这种做法由来已久,可以追溯到60年代的操作系统。BASIC的on error goto 语句就采用了这种方法。C++是建立在Ada基础上,java是建立在C++的基础上。这样做有以下好处。有效的减少了代码量,将描述具体操作的代码和专门纠正错误的代码分隔开了,便于读写,维护以及调试。
      “异常情形”是当前环境不能处理该错误,必须终止当前方法或作用域继续执行,必须跳出当前环境,把问题交给上一级环境进行处理。一个简单的例子就是除法当分母为零时。产生一个异常时,会发生几件事情。首先会在内存“堆”里,用new来创建一个异常对象。随后停止当前执行路径,从当前环境中释放异常对象的句柄。这时,异常处理机制会接管一切,并寻找一个“异常处理程序”来继续执行程序。“异常处理程序”的任务是将程序从错误状态中恢复:使程序要么换一种方式运行,要么继续执行。抛出异常的简单例子:if(t==null) throw new  NullPointerException();异常对象还可以传参 :if(t==null) throw new NullPointerException(“t==null”);
Java用try{}块捕获异常。异常处理用try {}catch(Type1 id1){//异常Type1处理 } catch(Type2 id2){//异常Type2处理}。处理异常的方法为中断与恢复。异常使用规范是采用throws关键字,后面跟着所有的异常类型 ,例如 void f() throws Type1,Type2{//….} 如果 void f()  只会抛出类型为RuntimeException异常。 捕获所有异常:catch(Exception e) {System.out.println("caught an exception");}重新抛出异常:catch(Exception e) {System.out.println("一个违例已经产生"); throw e;}。如果只是简单抛出当前异常,无论哪一级捕获该异常,并用printStackTrace()打印出来的堆栈信息是从异常初始开始到该级的信息,若想安装新的堆栈跟踪信息,可调用fillInStackTrace(),它会返回一个特殊的异常对象。异常有时候会丢失,因为所以异常都继承于Throwable,如果在try块里面抛出Throwable,则异常会丢失。
        Exception 是可以从任何标准 Java 库的类方法中“掷”出的基本类型。此外,它们亦可从我们自己的方法以及运行期偶发事件中“掷”出。java.lang.Exception这是程序能捕获的基本异常。其他异常都是从它衍生出去的。
        R u n t i m e E x c e p t i o n 属于 Java 的标准运行期检查的一部分。若对一个空句柄发出了调用, Java 会自动产生一个 NullPointerException 异常。
       我们可以创建自己的异常,当程序员创建自己的异常时,必须继承Exception类。
       当覆盖一个方法时,只能产生已在方法的基础类版本中定义的异常。
       在没有“垃圾收集”以及“自动调用破坏器”机制的一种语言中, finally 显得特别重要,因为程序员可用它担保内存的正确释放—— 无论在 try 块内部发生了什么状况。
       在java中,若要设置另一些东西, finally 就是必需的。例如,我们有时需要打开一个文件或者建立一个网络连接,或者在屏幕上画一些东西,甚至设置外部世界的一个开关,等等。
       异常匹配时,异常控制系统会按当初编写的顺序搜索“最接近”的控制器。一旦找到相符的控制器,就认为异常已得到控制,不再进行更多的搜索工作。 在异常和它的控制器之间,并不需要非常精确的匹配。

 

 
软件部        左顶