Java异常处理I

来源:互联网 发布:知乎上传图片 编辑:程序博客网 时间:2024/05/22 13:28

   Java异常处理

异常处理的基础知识:

即使是有经验的程序员,也难免出现编程错误。

编程错误的分类

编译错误(compilation error

原因:没有遵循语言的规则

解决方法:由编译程序检查发现

逻辑错误(logic error

原因:程序没有按照预期的方案执行

解决方法:利用调试技巧可以解决此类错误

运行时错误(runtime error

原因:在程序运行过程中,出现了不可能执行的操作。

解决方法:异常处理

运行时错误(runtime error

      在程序运行时出现的一些非正常的现象被称为运行时错误,如除数为0、数组下标越界、文件不存在、内存不够用等等。 

分类:根据错误性质将运行时错误分为两类

致命性的错误

错误处理一般由系统承担,语言本身不提供错误处理机制 

非致命性的异常

是可以检测和处理的,所以产生了相应的异常处理机制 

例:程序进入了死循环、递归无法结束、内存溢出等,这些运行错误是致命性的错误,只能在编程阶段解决,运行时程序本身无法解决,只能依靠其他程序干预,否则会一直处于非正常状态。

例:除数为0、操作数超出数据范围、文件并不存在、欲装入的类文件丢失、网络连接中断等,这类现象称为非致命性的异常。

异常处理的类层次

Java中预定义了很多异常类,每个异常类代表一种运行错误。

常用Exception类的子类:

异常类 描述

NullPointerException 空指针异常

ArrayIndexOutOfBoundsException 数组越界访问异常

ClassNotFoundException 试图访问一个根本不存在的类

IOException 输入/输出异常

NumberFormatException 错误的类型转换异常

ArrayStoreException 当向数组存入错误类型数据时

ArithmeticException 除数为0的算术异常

未被捕获“异常”

“异常”对象是Java运行时对某些“异常”情况作出反应而产生的。如果不处理“异常”会有什么样的情况发生?

8.1 0除异常。

class TestException1{

      public static void main(String args[]){

            int d=0;

            int a=42/d;///当执行到该语句时,系统检查到被零除,构造一个“异常”对象来引发异常 

      }

}

程序没有提供任何处理异常的异常处理程序,所以该异常被Java运行时系统的默认处理程序捕获,显示一个描述异常的字符串,打印异常发生处的堆栈轨迹并且终止程序 

class TestException2{

      static void subRoutine(){

  int d=0;

  int a=10/d;

      }

      public static void main(String args[]){

      TestException2.subRoutine();

      }

}

Java提供了异常处理机制,通过面向对象的方法来处理异常。

在程序运行的过程中,如果发生了异常,则该程序(或Java虚拟机)生成一个代表该异常类的对象(包含该异常的详细信息),并把交给运行时系统;

运行时系统从生成对象的代码开始,沿方法的调用栈逐层回溯查找,直到找到包含相应处理代码的方法,并把异常对象交给该方法,来处理这一异常。

异常捕获

1、发现异常的代码“抛出”异常

2、运行时系统“捕获”异常

3、由程序员编写的相应代码“处理”异常

使用try-catch-finally语句捕获和处理异常

格式:try{

                  //产生异常的语句////包含可能引发异常的语句

             }catch(异常类变量){

                  //异常处理代码

             }catch(异常类变量){

                 //异常处理代码///对异常进行处理的代码

             }[finally{

             }]

try语句块

将程序中可能出现异常的代码放入try块中。

try块中有语句引发异常时,系统将不再执行try块中未执行的语句,而执行匹配的catch块。

如果try块中没有语句引发异常,则程序执行完try块中的语句后不执行catch块中的语句,即跳过catch语句,继续执行后面的程序。

catch

每个try语句后面必须伴随一个或多个catch语句,用于捕捉try语句块所产生的异常并作相应的处理。

catch子句的目标是解决“异常”情况,并像没有出错一样继续运行。 

例如:try{  

                           int d=0;

                           int a=42/d;  

               }catch(ArithmeticException e)(指明该catch块所能捕捉的异常类型){

                        System.out.println(e.toString());

             }

8.3 try-catch语句的执行顺序。

        int a = 0,b = 0,c = 0;       Random r=new Random();

        for (int i = 0; i < 5; i++){

            try{

                b = r.nextInt();       c = r.nextInt();

                a = 12345 / ( b / c );

            }catch(ArithmeticException e){

                a = 0;

                System.out.print("有被0除异常 "); 

            }

            System.out.println("a:" + a);

        }

注意:一个try和它的catch语句组成了一个单元。catch子句的范围限制于try语句块中的语句。一个catch语句不能捕获另一个try声明所引发的异常(除非是嵌套的try语句情况)。被try保护的语句声明必须在一个大括号之内。try语句块不能单独使用。

多个catch
一个catch块只能处理一类异常,当try块中的语句组可能抛出多种异常时,就需要有多个catch块来分别处理各种异常。

try{

      int a=args.length;   System.out.println("a=" + a);

      int b=42/a;      int c[]={1};      c[42]=99;

}catch(ArithmeticException e){

      System.out.println("div by 0:" + e);

}catch(ArrayIndexOutOfBoundsException e){

      System.out.println("array index oob:" + e);

}

一个异常对象能否被一个catch块接收主要看该异常对象与catch块中声明的异常类的匹配情况,当它们满足下面条件中的任一条时,异常对象将被接受:

异常对象是catch块中声明的异常类的实例;

异常对象是catch块中声明的异常类的子类的实例;

异常对象实现了catch块中声明的异常类的接口。

当使用多个catch块时,需注意catch子句排列顺序--先特殊到一般,也就是子类在父类前面。如果子类在父类后面,子类将永远不会到达。 

try语句的嵌套
一个try语句可以在另一个try块内部----try语句的嵌套。

每次进入try语句,异常的前后关系都会被压入堆栈。如果一个内部的try语句不含特殊异常的catch处理程序,堆栈将弹出,下一个try语句的catch处理程序将检查是否与之匹配。

这个过程将继续直到一个catch语句匹配成功,或者是直到所有的嵌套try语句被检查耗尽。

如果没有catch语句匹配,Java的运行时系统将处理这个异常。 

8.6 运用嵌套try语句的示例。 

分析:

1)当在没有命令行参数的情况下运行程序,外面的try块将产生一个被零除的异常。

2)程序在有一个命令行参数条件下运行,内部的try块将产生一个被零除的异常。因为与内部的catch块不匹配,它将把该异常传给外部的catch块来处理。

3)如果在具有两个命令行参数的条件下执行该程序,由内部try块产生一个数组下标越界异常,由内部的catch块处理。 

finally语句块

某些情况下,不管异常是否发生,都需要处理某些语句,那么就将这些语句放到finally语句块中。finally语句所包含的代码在任何情况下都会被执行。

一个try语句至少有一个catch语句或finally语句与之匹配,但匹配的catch可以有多个,而finally语句只能有一个,并且finally语句并非必须有的。

8.7 finally的用法示例。main()方法中的语句为:

String[] friends={"Tom","葫芦娃","孙悟空"};

try{

for(int i=0;i<5;i++){

System.out.println(friends[i]);

}

}catch(ArrayIndexOutOfBoundsException e){

System.out.println("index err");

return;

}finally{

System.out.println("in finally block!");

}

System.out.println("this is the end");

虽然catch块中有return语句,finally语句块仍旧会被执行

未完待续。。。。。
原创粉丝点击