天天看点

异常的捕获及处理

<b>异常:</b>异常是指中断程序正常执行的一种指令流

       在JAVA程序中一旦出现了异常,而程序又没有及时处理的情况下,那么程序会中断执行。

<b>例如</b>,观察以下的代码:

public class Demo22{

         public static void main(String args[]){

                   int i = 10 ;

                   int j = 0 ;

                   System.out.println(" --------- 计算开始 ---------") ;

                   <b>System.out.println("i / j = " + (i / j)) ;   </b><b>à</b><b> </b><b>此段代码出现了异常</b><b></b>

                   System.out.println(" --------- 计算结束 ---------") ;

         }

};

       以上代码编译的时候不存在任何的问题,那么执行时,出错了,打印内容如下:

--------- 计算开始 ---------

Exception in thread "main" java.lang.ArithmeticException: / by zero

        at Demo22.main(Demo22.java:6)

       整个程序,在出现异常的代码之后不再被执行了,异常之前的程序呢?正确的执行了。

       那么在JAVA中我们所处理的异常都属于运行时异常,即:执行JAVA程序的时候出现的错误,那么实际上对于JAVA的异常分类应该按如下的形式划分:

       ArithmeticException à RuntimeException à Exception(往往是要由用户自己处理的)

       所以对于异常而言,它是一个统称,代表了:

       <b>Throwable</b><b>(可能的抛出)</b>

|- <b>Exception</b>:表示需要人为处理的异常,指的是程序的错误 à 因为程序的错误较多,所以就习惯了把所有的错误都统一成为异常。

              |- Error:表示JVM错误,人为不能处理

<b>异常的处理格式如下:</b>

try{

       包含可能出现错误的代码段 ;

}catch(出错的类型 出错的对象){

       对于错误的处理语句 ;

}

       那么使用如上的格式修改之前的代码,保证程序可以正确的执行完:

public class Demo23{

                   try{

                            System.out.println("i / j = " + (i / j)) ;

                   }catch(ArithmeticException e){

                            System.out.println("计算出现了错误。。。") ;

                   }

       但是以上的程序依然存在了些小小的问题,例如:对于计算,往往应该由用户自己输入数据,所以此时可以通过接收参数为其输入数据。代码如下:

public class Demo24{

<b>                            i = Integer.parseInt(args[0]) ;</b>

<b>                            j = Integer.parseInt(args[1]) ;</b>

       如果现在输入的内容是正确的数字,则程序不会有任何的问题,但是既然数据是由用户自己输入的,那么肯定会输入各种违法的数据。

       存在的问题:

              · 不输入任何参数,出现数组越界:ArrayIndexOutOfBoundsException

              · 输入的参数不是数字,出现了数字格式转换错误:NumberFormatException

              · 输入的被除数是0,出现算术错误:ArithmeticException

       在以上的错误之中,只有算术错误被处理了,因为在程序上具备了算术错误的处理能力。那么也就意味着,现在的异常处理并不完善,需要加入更多的处理,所以需要编写更多的catch。

       以上的程序修改为:

                            i = Integer.parseInt(args[0]) ;

                            j = Integer.parseInt(args[1]) ;

                            System.out.println("算术错误。。。"+e) ;

                   catch(ArrayIndexOutOfBoundsException e){

                            System.out.println("没有输入参数。。。"+e) ;

                   catch(NumberFormatException e){

                            System.out.println("输入的内容不是数字。。。"+e) ;

       但是会发现比较麻烦,因为现在已经知道了的是三个错误,那么对于很多未知道的错误呢?那么此时,就需要分析异常的产生过程。

       发现catch中接收的内容都是对象,那么也就意味着,所谓的异常,就是自动产生了一个异常类的实例化对象。一出错就产生。

       对象有一个特点,可以向上自动转型,Exception是用户需要处理的最大异常,那么证明所有的对象都可以向Exception转换。

public class Demo25{

                   catch(Exception e){

                            System.out.println("其他异常。。。"+e) ;

<b>注意:</b>

       如果在程序中出现了多个catch语句,则捕获更粗的catch要放在捕获更细的catch之后。

                   }<b>catch(Exception e){</b>

<b>                            System.out.println("</b><b>其他异常。。。</b><b>"+e) ;</b>

<b>                   }</b>catch(ArithmeticException e){

                   }catch(ArrayIndexOutOfBoundsException e){

                   }catch(NumberFormatException e){

       则编译的时候出现了以下的错误,说是许多的异常已经被捕获了。

Demo25.java:14: 已捕捉到异常 java.lang.ArithmeticException

                catch(ArithmeticException e){

                ^

Demo25.java:17: 已捕捉到异常 java.lang.ArrayIndexOutOfBoundsException

                catch(ArrayIndexOutOfBoundsException e){

Demo25.java:20: 已捕捉到异常 java.lang.NumberFormatException

                catch(NumberFormatException e){

3 错误

       既然所有异常类的对象都可以向Exception转换,那么是不是直接使用Exception接收更方便?

public class Demo26{

                            System.out.println("***************************") ;

                   }catch(<b>Exception e</b>){

                            System.out.println(e) ;

       以上是异常处理的一种格式,实际上异常处理还有另外一种格式,就是说,可以为异常做一个统一的出口,不管是否发生了异常,都要执行此代码:

         包含可能出现错误的代码段 ;

         对于错误的处理语句 ;

}finally{

         不管是否出现异常,都执行此代码 ;

       代码如下:

public class Demo27{

                   }catch(Exception e){

                   }<b>finally{   </b><b>à</b><b> </b><b>典型的程序出口</b><b></b>

<b>                            System.out.println("</b><b>不管是否存在异常,此代码都会被执行。。。</b><b>") ;</b>

<b>                   }</b>

在异常处理中还有两个很重要的关键字

       · throws:在方法的声明处使用,表示此方法不处理异常,而交给被调用处处理。

       · throw:表示人为的抛出一个异常。

<b>例如:</b>定义一个数学类,里面有一个除法

class Math{

         // 此代码有可能发生问题,也有可能不发生问题

         // 一旦发生问题,找调用处,谁调用的此方法,谁去处理

         public int div(int i,int j) throws Exception{

                   return i / j ;

public class Demo28{

                   Math m = new Math() ;

                   System.out.println(m.div(10,2)) ;

       按规定来说,此方法在调用的时候使用异常的捕获,如果不使用,则编译时出现以下的错误提示:

Demo28.java:11: 未报告的异常 java.lang.Exception;必须对其进行捕捉或声明以便抛出

                System.out.println(m.div(10,2)) ;

                                        ^

1 错误

       所以对于调用有throws声明的方法,必须使用try…catch:

                            System.out.println(m.div(10,0)) ;

       问?既然main方法是一个方法,那么能不能在主方法上编写throws语句呢?肯定是可以的

public class Demo29{

         public static void main(String args[]) throws Exception{

                   System.out.println(m.div(10,0)) ;

       观察错误的提示:

        at Math.div(Demo29.java:5)

        at Demo29.main(Demo29.java:11)

       可以发现以上的错误提示与不使用try…catch效果是一样的,证明所有的错误都交给了JVM进行处理,实际上在JAVA中默认的处理方式也就是使用JVM完成。

       throw:表示在程序中人为的抛出一个异常,而且必须使用try…catch进行处理。

public class Demo30{

                            throw new Exception("我自己乐意抛。。。") ;

       因为对于异常而言,最终结果肯定都是抛出一个异常的实例化对象。所以是自己抛还是系统抛都肯定需要进行异常的捕获及处理。

       设计一个除法操作,在操作之前编写:计算开始,在操作之后编写计算结束,中间不管是否出现了错误,都要打印这样两句话,问:该如何实现?

                   System.out.println(" ======== 计算开始 =========") ;

                   int temp = 0 ;

                            temp = i / j ;

                            throw e ;

                   }finally{

                            System.out.println(" ======== 计算结束 =========") ;

                   return temp ;

public class Demo31{

         public static void main(String artgs[]){

                  try{

                            System.out.println(m.div(1,0)) ;

       一般而言,对于throw、throws、finally往往会一起使用。

<b>自定义异常:</b>

       一个类只要继承了Exception就可以称为一个异常类。

class MyException extends Exception{

         public MyException(String msg){

                   super(msg) ;

public class Demo32{

                            throw new MyException("自己定义玩的。。") ;

<b>注意点:</b>

       · throw与throws的区别?

              |- throw:是人为抛出异常

              |- throws:方法声明处使用,表示在方法中不处理异常

       · final与finally

              |- final:定义类、方法、常量

              |- finally:异常的统一出口

本文转自 李兴华 51CTO博客,原文链接:http://blog.51cto.com/lixinghua/96928,如需转载请自行联系原作者