• java中异常处理


       java的中异常祖先是Throwable,Throwable的直接子类是Exception和Error。

          Error通过单词我们就知道,是错误的意思,这种错误一般是jvm运行产生的错误,出现这种错误,我们的程序不能解决,比如内存溢出oom,堆溢出等。这种错误,我们不必处理,直接让jvm抛出报错,我们没办法解决就不管了。

         Exception中文意思是异常,那么Exception又分为检查性异常和非检查性异常。比如RuntimeException类及子类就是非检查性异处,表示运行时出现的异常,有数组越界,空指针异常,我们也可以不进行处理,让jvm自己抛出异常,当然如果我们可以预见这种异常的话,最好在程序中进行判断检查,程序写健壮些,有的这种异常就可以避免了。effect java有这种处理的推荐,具体的可以看看这本书。

        Exception还有一类是检查性异常,这是除RuntimeException类及子类外的Exception类和Exception类的其他子类。检查性异常,必须要进行异常处理的或者抛出,否则编译器会报错。

          

       异常处理一般用到以下几个关键字try,catch,finally,throws,throw,下面我逐个做一个说明。

        try:

        对于可能会抛出异常的代码一般放在try{}代码块中,比如:

    [java] view plain copy
     
    1. try {  
    [java] view plain copy
     
    1. int   i=2/0;  
    2.     t.test1();  
    3.     //System.out.println("kkk"+st);  
    4. catch (Exception e) {  
    5.     // TODO Auto-generated catch block  
    6.     System.out.println("i will catch you....");  
    7.     e.printStackTrace();  
    8. }  

    上面的代码2/0,肯定会抛出异常的,所以需要放在try{}块中,在try块中,如果哪一行抛出了异常,那么try块后面的代码将不再执行,将直接进入异常处理代码块。

      catch:

        catch(Excetion e){}这种结构是用来处理,try代码块中抛出的异常的,可以有很多的catch代码块,不过要注意的是,当有很多catch代码块,并且catch里面的参数有父子关系的时候,catch里面的参数一定要是子类在前面,父类在后面,因为按catch代码块出现的先后顺序匹配抛出的异常,一旦抛出的异常是哪个catch里面参数的子类或同类,那么就可以被这个catch代码块进行处理,那么其他的catch代码块就算也符合这种条件也不在进行处理了,如果有finally代码块的话就直接进入finally代码块中,没得则直接运行catch代码块后面的代码了。

        finally:

        finally代码块是异常处理中一定会执行的代码块,就算没得异常也会执行,有异常则进入catch代码块中处理后,在进入finally中处理。

        在这里要注意一点,假如在try代码块中有return 语句,那么也是先执行finally里面的代码块后在执行return语句的。

     还需注意一点的是,函数的返回值,是最后活动栈的栈顶的值。如果try进行return了,那么在finally中我也进行return,那么finally代码块里面的return的值在栈顶,所以会返回finally中return的值。有如下测试代码。

    [java] view plain copy
     
    1. package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException(){  
    7.         try{  
    8.             return "I am in try";  
    9.         }finally{  
    10.             return "I am in finally";  
    11.         }  
    12.     }  
    13.       
    14.       
    15.     public static void main(String[] args) {  
    16.         // TODO Auto-generated method stub  
    17.   
    18.         TestException3 te=new TestException3();  
    19.         System.out.println(te.testException());  
    20.     }  
    21.   
    22. }  



    运行结果是:

       I am in finally

    注意我这里是测试所以在finally中进行return了,一般不推荐在finally中进行return。

        throws:

        throws的用法是在      函数名(参数1,参数2.....)throws 异常类1,异常类2,异常类3.....{}

       throws是表明这个函数可能会有异常产生,但是函数不进行异常处理,函数将向上抛异常,把异常处理交给函数的调用处进行处理,如果调用处,不进行处理则可以在进行向上抛。。。直到有地方进行try{}catch(){}异常处理,或者最后抛给jvm(不建议这么使用)。

    [java] view plain copy
     
    1. package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException() throws Exception{  
    7.         /*try{ 
    8.             return "I am in try"; 
    9.         }finally{ 
    10.             return "I am in finally"; 
    11.         }*/  
    12.         System.out.println("我不进行异常处理,我将异常向上抛,throws");  
    13.         int i=2/0;  
    14.         System.out.println("有异常我将得不到执行。。。。");  
    15.         return "我是使用throws抛的异常";  
    16.     }  
    17.       
    18.       
    19.     public static void main(String[] args) {  
    20.         // TODO Auto-generated method stub  
    21.   
    22.         TestException3 te=new TestException3();  
    23.         try {  
    24.             System.out.println(te.testException());  
    25.         } catch (Exception e) {  
    26.             // TODO Auto-generated catch block  
    27.             e.printStackTrace();  
    28.         }  
    29.     }  
    30.   
    31. }  



    输出结果:

    [java] view plain copy
     
    1. <span style="font-size:18px;">我不进行异常处理,我将异常向上抛,throws  
    2. java.lang.ArithmeticException: / by zero  
    3.     at com.wj.exception.TestException3.testException(TestException3.java:13)  
    4.     at com.wj.exception.TestException3.main(TestException3.java:24)  
    5. </span>  



           throw:

         throw的作用是具体的抛出一个异常类对象,一般在方法里面使用。当在try代码块中使用的时候,直接进入catch代码块中进行处理。比如:

    [java] view plain copy
     
    1. package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException(){  
    7.         try{  
    8.             throw new Exception("i is throw exception");  
    9.         }catch(Exception e){  
    10.             System.out.println("我处理throw抛出的异常");  
    11.         }finally{  
    12.             System.out.println("我执行finally代码块 ");  
    13.               
    14.         }  
    15.         System.out.println("异常处理结束!!!");  
    16.         return "I am in finally";  
    17.           
    18.     }  
    19.       
    20.       
    21.     public static void main(String[] args) {  
    22.         // TODO Auto-generated method stub  
    23.   
    24.         TestException3 te=new TestException3();  
    25.           
    26.         System.out.println(te.testException());  
    27.           
    28.     }  
    29.   
    30. }  



    允许结果:

    我处理throw抛出的异常
    我执行finally代码块


    异常处理结束!!!
    I am in finally

            throw手动抛出的异常需要从里到到外查找处理的try代码块,没有处理话,就需要把方法后面加throws,把异常向上抛。看如下代码:

        1

    [java] view plain copy
     
    1. package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException(){  
    7.         try{  
    8.             int i=3/0;  
    9.         }catch(Exception e){  
    10.             throw new Exception();  
    11.         }finally{  
    12.             System.out.println("我执行finally代码块 ");  
    13.               
    14.         }  
    15.         //System.out.println("异常处理结束!!!");  
    16.         return "I am in finally";  
    17.           
    18.     }  
    19.       
    20.       
    21.     public static void main(String[] args) {  
    22.         // TODO Auto-generated method stub  
    23.   
    24.         TestException3 te=new TestException3();  
    25.           
    26.         System.out.println(te.testException());  
    27.           
    28.     }  
    29.   
    30. }  

    2

    上面的代码在编译器里面会出现错误,提示我们使用throws抛出异常,或者把throw new Exception()进行因此处理,改成这样的

    [java] view plain copy
     
    1. <pre name="code" class="java">package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException() {  
    7.         try{  
    8.             int i=3/0;  
    9.         }catch(Exception e){  
    10.             try {  
    11.                 throw new Exception();  
    12.             } catch (Exception e1) {  
    13.                 // TODO Auto-generated catch block  
    14.                 e1.printStackTrace();  
    15.             }  
    16.         }finally{  
    17.             System.out.println("我执行finally代码块 ");  
    18.               
    19.         }  
    20.         //System.out.println("异常处理结束!!!");  
    21.         return "I am in finally";  
    22.           
    23.     }  
    24.       
    25.       
    26.     public static void main(String[] args)  {  
    27.         // TODO Auto-generated method stub  
    28.   
    29.         TestException3 te=new TestException3();  
    30.           
    31.           
    32.             System.out.println(te.testException());  
    33.           
    34.           
    35.     }  
    36.   
    37. }  
    
    
    
    

    输出结果:

    [java] view plain copy
     
    1. java.lang.Exception  
    2.     at com.wj.exception.TestException3.testException(TestException3.java:11)  
    3.     at com.wj.exception.TestException3.main(TestException3.java:32)  
    4. 我执行finally代码块  
    5.   
    6. I am in finally  



    3

    或者说是这样的:

    [java] view plain copy
     
    1. <pre name="code" class="java">package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException()  throws Exception{  
    7.         try{  
    8.             int i=3/0;  
    9.         }catch(Exception e){  
    10.               
    11.                 throw new Exception();  
    12.               
    13.         }finally{  
    14.             System.out.println("我执行finally代码块 ");  
    15.         }  
    16.         //System.out.println("异常处理结束!!!");  
    17.     return "I am in finally";  
    18.           
    19.     }  
    20.       
    21.       
    22.     public static void main(String[] args)  {  
    23.         // TODO Auto-generated method stub  
    24.   
    25.         TestException3 te=new TestException3();  
    26.           
    27.         try {  
    28.             System.out.println(te.testException());  
    29.         } catch (Exception e) {  
    30.             // TODO Auto-generated catch block  
    31.             e.printStackTrace();  
    32.         }  
    33.           
    34.     }  
    35.   
    36. }  


    输出结果:

    
    
    [java] view plain copy
     
    1. 我执行finally代码块  
    2.   
    3.   
    4. java.lang.Exception  
    5. <span style="white-space:pre">    </span>at com.wj.exception.TestException3.testException(TestException3.java:11)  
    6. <span style="white-space:pre">    </span>at com.wj.exception.TestException3.main(TestException3.java:28)  

    4

    这样改,很简单,但是还有一种更加奇葩的改法,可以使编译器不出错,如下:

    [java] view plain copy
     
    1. package com.wj.exception;  
    2.   
    3. public class TestException3 {  
    4.   
    5.       
    6.     public String testException()  {  
    7.         try{  
    8.             int i=3/0;  
    9.         }catch(Exception e){  
    10.               
    11.                 throw new Exception();  
    12.               
    13.         }finally{  
    14.             System.out.println("我执行finally代码块 ");  
    15.             return "I am in finally";  
    16.         }  
    17.         //System.out.println("异常处理结束!!!");  
    18.         //return "I am in finally";  
    19.           
    20.     }  
    21.       
    22.       
    23.     public static void main(String[] args) {  
    24.         // TODO Auto-generated method stub  
    25.   
    26.         TestException3 te=new TestException3();  
    27.           
    28.         System.out.println(te.testException());  
    29.           
    30.     }  
    31.   
    32. }  


    输出:

    我执行finally代码块
    I am in finally

         发现没有第四个代码,本来是跑出了一个异常的,但是没有输出任何的异常信息。而且把函数返回值改为void,在finally里面不使用return,则又会报错,这一点我不是很明白了,难道在catch里面使用throw抛出的异常,在finally代码块里面使用return语句后,就被处理了嘛?要是被处理了怎么没得异常输出,还是输出的异常信息在栈里面被覆盖了?知道怎么回事的朋友,可以交流下。

    看了上面那么多,你是否对java中的异常有一定理解了?

    代码如下了:

    [java] view plain copy
     
    1. package com.wj.exception;  
    2.   
    3. public class TestException1 {  
    4.   
    5.     boolean testEx() throws Exception {    
    6.     boolean ret = true;    
    7.     try {    
    8.     ret = testEx1();    
    9.     } catch (Exception e) {    
    10.     System.out.println("testEx, catch exception");    
    11.     ret = false;    
    12.     throw e;    
    13.     } finally {    
    14.     System.out.println("testEx, finally; return value=" + ret);    
    15.     return ret;    
    16.     }    
    17.     }    
    18.   
    19.       
    20.     boolean testEx1() throws Exception {    
    21.     boolean ret = true;    
    22.     try {    
    23.     ret = testEx2();    
    24.     if (!ret) {    
    25.     return false;    
    26.     }    
    27.     System.out.println("testEx1, at the end of try");    
    28.     return ret;    
    29.     } catch (Exception e) {    
    30.     System.out.println("testEx1, catch exception");    
    31.     ret = false;    
    32.     throw e;    
    33.     } finally {    
    34.     System.out.println("testEx1, finally; return value=" + ret);    
    35.     return ret;    
    36.     }    
    37.     }    
    38.   
    39.     boolean testEx2() throws Exception {    
    40.     boolean ret = true;    
    41.         try {    
    42.         int b = 12;    
    43.         int c;    
    44.         for (int i = 2; i >= -2; i--) {    
    45.         c = b / i;    
    46.         System.out.println("i=" + i);    
    47.         }    
    48.         return true;    
    49.         } catch (Exception e) {    
    50.         System.out.println("testEx2, catch exception");    
    51.         ret = false;    
    52.         throw e;  
    53.         } finally {    
    54.         System.out.println("testEx2, finally; return value=" + ret);    
    55.         return ret;    
    56.         }    
    57.         }    
    58.   
    59.     /** 
    60.      * @param args 
    61.      */  
    62.     public static void main(String[] args) {  
    63.         // TODO Auto-generated method stub  
    64.   
    65.         TestException1 testException1 = new TestException1();    
    66.         try {    
    67.         testException1.testEx();    
    68.         } catch (Exception e) {    
    69.             System.out.println("结束 ");  
    70.         e.printStackTrace();    
    71.         }    
    72.   
    73.     }  
    74.   
    75. }  


    如果不看答案,你能说出运行结果嘛?你可以到自己的编译器中运行下看下结果,在进行debug下,看看是否和你想的一样了。

          上面运行的结果如下:

    i=2
    i=1
    testEx2, catch exception
    testEx2, finally; return value=false
    testEx1, finally; return value=false
    testEx, finally; return value=false

  • 相关阅读:
    小数的进制转换
    水题 O
    水题 J
    水题T,二进制转16进制
    水题B
    水题C
    HDU 2042
    HDU 2041
    Index For SQL Server
    Learning Note For Angular
  • 原文地址:https://www.cnblogs.com/luanyichao/p/8214107.html
Copyright © 2020-2023  润新知