java中異常與return


抽時間整理了下java中異常與return,以前這塊總是弄混淆,覺得還是寫下來慢慢整理比較好。由於水平有限,僅供參考。廢話不多說,直接上代碼。

下面是兩個方法:

 1      public static int throwReturn(){
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             ret++;
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             //ret++;
10             return ret;
11         }finally{
12             System.out.println("finally block invoked!!!");
13             ret++;
14             System.out.println("finally block invoked, ret is " + ret);
15         }
16         
17     }  
 1    public static int finallyReturn(){
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             ret++;
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             //ret++;
10             return ret;
11         }finally{
12             System.out.println("finally block invoked!!!");
13             ret++;
14             System.out.println("finally block invoked, ret is " + ret);
15             return ret;
16         }
17         
18     }

然后在主方法中分別調用兩個方法:

1 public static void main(String args[]){
2   System.out.println("throwReturn:" + throwReturn());
3   //System.out.println("finallyReturn:" + finallyReturn());  
4 }

第一個方法輸出結果:

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
throwReturn:0

throwRetrun方法返回的結果並不是我預想的1,而是0。

個人分析:

  1. 程序執行到throwReturn方法的第4行時由於除0而出錯,程序進入catch塊,首先會執行打印輸出:catch block / by zero
  2. 接下來會執行catch塊的return ret語句,碰到return語句方法會返回退出,而finally語句又是必須執行的,此時程序會將return的結果值暫存起來,繼續執行finally塊。
  3. 進入finally塊后會輸出:finally block invoked!!! 和finally block invoked, ret is 1
  4. finally塊執行完成后程序會回到return處,並返回當時暫存的值

第二個方法的輸出結果:

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
finallyReturn:1

哎,這次的輸出結果是1了。

仔細比較兩個方法發現第二個方法,在finally語句中多了一個return ret;程序的執行過程同上面基本上是一樣的,只是在最終執行finally代碼塊是碰到了return語句,此時程序就直接將ret的值返回了,而此時ret的值是1,最后輸出:finallyReturn:1

接下來我們再看2個方法:

 

 1     public static int throwException() throws Exception{
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             System.out.println("ret:" + ret);
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             throw e;
10         }finally{
11             System.out.println("finally block invoked!!!");
12             ret++;
13             System.out.println("finally block invoked, ret is " + ret);
14         }
15         
16     }

 

 1 public static int finallyThrowException() throws Exception{
 2         int ret = 0;
 3         try{
 4             ret = 10/0 ;
 5             System.out.println("ret:" + ret);
 6             return ret;
 7         }catch(Exception e){
 8             System.out.println("catch block " + e.getMessage());
 9             throw e;
10         }finally{
11             System.out.println("finally block invoked!!!");
12             ret++;
13             System.out.println("finally block invoked, ret is " + ret);
14             return ret;
15         }
16         
17     }

然后在主方法中分別調用兩個上面方法:

 

 1 public static void main(String args[]){
 2        try {
 3             System.out.println("throwException:" + throwException());
 4         } catch (Exception e) {
 5             System.out.println("捕獲到throwException方法拋出的異常," + e.getMessage());
 6         } 
 7 
 8         /*try {
 9             System.out.println("finallyThrowException:" + finallyThrowException());
10         } catch (Exception e) {
11             System.out.println("捕獲到finallyThrowException方法拋出的異常," + e.getMessage());
12         }*/     
13 }

 

第一個方法輸出結果:

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
捕獲到throwException方法拋出的異常,/ by zero

個人分析:

  1. throwException方法執行到第4行時,因為除0操作拋出異常,程序進入catch塊,首先執行打印輸出:catch block / by zero
  2. 接下來會執行catch塊的throw e語句,向上拋出異常,而finally語句又是必須執行的,此時程序會先執行finally塊。
  3. 進入finally塊后會輸出:finally block invoked!!! 和finally block invoked, ret is 1
  4. finally塊執行完成后程序會回到catch塊throw處,將捕獲的異常向上拋出
  5. 在main方法中會捕獲到throwException方法拋出的異常而進入catch塊,所以會輸出:捕獲到throwException方法拋出的異常,/ by zero

第二個方法的輸出結果:

 

catch block / by zero
finally block invoked!!!
finally block invoked, ret is 1
finallyThrowException:1

 

觀察輸出結果會發現,主方法並沒有捕獲到finallyThrowException方法調用時的異常(catch塊的打印沒有執行)。

這兩個方法的主要區別也是在於:在finallyThrowException方法的finally塊中多出了return ret語句。調用finallyThrowException方法的執行過程同調用throwException方法基本一致。

  1. finallyThrowException方法執行時,因為除0操作拋出異常,程序進入catch塊,首先執行打印輸出:catch block / by zero
  2. 接下來會執行catch塊的throw e語句,向上拋出異常,而finally語句又是必須執行的,此時程序會先執行finally塊。
  3. 進入finally塊后會輸出:finally block invoked!!! 和finally block invoked, ret is 1
  4. finally塊執行到return ret時,該方法直接返回了ret的值,
  5. 在main方法中得到finallyThrowException的返回值后輸出:finallyThrowException:1

finallyThrowException方法執行結果可以看出方法執行時的異常被丟失了


最后再來看一個小例子

 1 public static void finallyWork(){
 2         int count = 0;
 3         while(true){
 4             try{
 5                 if(count++ == 0){
 6                     throw new Exception("my error");
 7                 }
 8                 System.out.println("invoked ...");
 9             }catch(Exception e){
10                 System.out.println("catched exception:" + e.getMessage());            
11             }finally{
12                 System.out.println("finally block invoked!!!");
13                 if(count == 2){
14                     break;
15                 }
16             }
17         }
18     }

這個小例子的主要思路是當java中的異常不允許我們回到異常拋出的地點時,我們可以將try塊放到循環里,這樣程序就又可以回到異常的拋出點了,可以同時設置一個計數器,當累積嘗試一定的次數后程序就退出。

ok,就說這么多了,下面附上完整代碼:

package tt;

public class FinallyWorks {

    /**
     * @param args
     */
    public static void main(String[] args) {
         
        //finallyWork();
        /*
         *<output begin>
         *        catch block / by zero
         *        finally block invoked!!!
         *        finally block invoked, ret is 1
         *          throwReturn:0
         *</output end>
         *從輸出結果中可以看出程序在int temp = 10/0;這一行拋出異常,直接進入catch塊,首先輸出打印catch block...,繼續往下執行時碰到return語句,由於程序
         *存在finally語句,在程序返回之前需要執行finally語句。那么此時程序會將return的結果值暫時存起來,繼續執行finally,從輸出上可以看出finally執行后ret
         *的值變為了1,而整個方法最終的返回結果是0,說明return的是之前暫存的值。
         * */
        //System.out.println("throwReturn:" + throwReturn());
        
        /*
         * <output begin>
         *        catch block / by zero
         *        finally block invoked!!!
         *        finally block invoked, ret is 1
         *          finallyReturn:1
         *</output end>
         *從輸出結果中可以看出程序在int temp = 10/0;這一行拋出異常,直接進入catch塊,首先輸出打印catch block...,繼續往下執行時碰到return語句,由於程序
         *存在finally語句,在程序返回之前需要執行finally語句。那么此時程序會將return的結果值暫時存起來,繼續執行finally,從輸出上可以看出finally執行后ret
         *的值變為了1,有在finally塊中碰到了return語句,方法就直接返回了,所以方法結果返回了1。
         * */
        //System.out.println("finallyReturn:" + finallyReturn());
        
        /*
         *<output begin>
         *        catch block / by zero
         *        finally block invoked!!!
         *        finally block invoked, ret is 1
         *          捕獲到throwException方法拋出的異常,/ by zero
         *</output end>
         *從輸出結果中可以看出在調用throwException方法是出現異常,程序進入該方法的catch塊中,輸出:catch block / by zero
         *由於存在finally,程序會先執行完finally語句輸出:finally block invoked!!! 和 finally block invoked, ret is 1
         *然后將捕獲到的異常拋向上層。上層的main方法catch到這個異常之后會輸出:捕獲到throwException方法拋出的異常,/ by zero
         *《注意throwException:那句打印是不會輸出的》
         * */
        
        /*try {
            System.out.println("throwException:" + throwException());
        } catch (Exception e) {
            System.out.println("捕獲到throwException方法拋出的異常," + e.getMessage());
        }*/
        
        
        /*
         *<output begin>
         *           catch block / by zero
         *        finally block invoked!!!
         *        finally block invoked, ret is 1
         *          finallyThrowException:1
         *</output end>
         *從輸出結果中可以看出在調用finallyThrowException方法是出現異常,程序進入該方法的catch塊中,輸出:catch block / by zero
         *由於存在finally,程序會先執行完finally語句輸出:finally block invoked!!! 和 finally block invoked, ret is 1
         *之后程序執行到finally塊中return語句,直接返回了ret的值,主方法接受到這個返回值后輸出:finallyThrowException:1
         *《注意主方法中catch塊代碼並沒有被執行,這就說明了finallyThrowException方法中異常被丟失了》
         * */
        try {
            System.out.println("finallyThrowException:" + finallyThrowException());
        } catch (Exception e) {
            System.out.println("捕獲到finallyThrowException方法拋出的異常," + e.getMessage());
        }
    }
    
    public static int throwException() throws Exception{
        int ret = 0;
        try{
            ret = 10/0 ;
            System.out.println("ret:" + ret);
            return ret;
        }catch(Exception e){
            System.out.println("catch block " + e.getMessage());
            throw e;
        }finally{
            System.out.println("finally block invoked!!!");
            ret++;
            System.out.println("finally block invoked, ret is " + ret);
        }
        
    }
    
    public static int finallyThrowException() throws Exception{
        int ret = 0;
        try{
            ret = 10/0 ;
            System.out.println("ret:" + ret);
            return ret;
        }catch(Exception e){
            System.out.println("catch block " + e.getMessage());
            throw e;
        }finally{
            System.out.println("finally block invoked!!!");
            ret++;
            System.out.println("finally block invoked, ret is " + ret);
            return ret;
        }
        
    }
    
    public static int throwReturn(){
        int ret = 0;
        try{
            ret = 10/0 ;
            ret++;
            return ret;
        }catch(Exception e){
            System.out.println("catch block " + e.getMessage());
            //ret++;
            return ret;
        }finally{
            System.out.println("finally block invoked!!!");
            ret++;
            System.out.println("finally block invoked, ret is " + ret);
        }
        
    }
    
    public static int finallyReturn(){
        int ret = 0;
        try{
            ret = 10/0 ;
            ret++;
            return ret;
        }catch(Exception e){
            System.out.println("catch block " + e.getMessage());
            //ret++;
            return ret;
        }finally{
            System.out.println("finally block invoked!!!");
            ret++;
            System.out.println("finally block invoked, ret is " + ret);
            return ret;
        }
        
    }
    /**
     * 當java中的異常不允許我們回到異常拋出的地點時,我們可以將try塊放到循環里,
     * 這樣程序就又可以回到異常的拋出點了,可以同時設置一個計數器,
     * 當累積嘗試一定的次數后程序就退出。
     */
    public static void finallyWork(){
        int count = 0;
        while(true){
            try{
                if(count++ == 0){
                    throw new Exception("my error");
                }
                System.out.println("invoked ...");
            }catch(Exception e){
                System.out.println("catched exception:" + e.getMessage());            
            }finally{
                System.out.println("finally block invoked!!!");
                if(count == 2){
                    break;
                }
            }
        }
    }

}

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM