Java運行時異常和受檢查異常


    在用Dubbo進行遠程調用時候,如果遠程服務執行超時,並且調用端設置的Dubbo超時時間小於遠程的超時時間時候,會拋出異常,而且該異常屬於運行時候異常(一般時候比如數據庫連接超時異常屬於非運行時異常,需要try{}catch{}捕捉),不需要try{}catch{}捕捉,從而可能導致前端程序直接終止,得不到結果。可以將dubbo的超時時間設置大於服務端的超時時間(超時時,dubbo默認重試2次,共3次):

<dubbo:reference id="xxxService" interface="xxx.IxxxService" timeout="5000" retries="0" />

    正確運用異常處理機制,有助於提高程序的健壯性。

    所謂程序的健壯性,就是指程序在多數情況下能夠正常運行,返回預期的正確結果;如果偶爾遇到異常情況,程序也能采取周到的解決措施。

    受檢查異常表示程序可以處理的異常,如果拋出異常的方法本身不能處理它,那么方法調用者應該去處理它,從而使程序恢復運行,不至於終止程序。例如,噴墨打印機在打印文件時,如果紙用完或者墨水用完,就會暫停打印,等待用戶添加打印紙或更換墨盒,如果用戶添加了打印紙或更換了墨盒,就能繼續打印。

    可以用OutOfPaperException類和OutOfInkException類來表示紙張用完和墨水用完這兩種異常情況,由於這些異常是可修復的,因此是受檢查異常,可以把它們定義為Exception類的子類:

public class OutOfPaperException extends Exception{…}    
public class OutOfInkException extends Exception{…}  

    以下是打印機的print()方法:

public void print()  
{  
    while(文件未打印完)  
    {  
        try  
        {   
            打印一行        
        }  
        catch(OutOfInkException e)  
        {          
             do  
             {  
                 等待用戶更換墨盒  
             }  
             while(用戶沒有更換墨盒)        
        }  
        catch(OutOfPaperException e)  
        {    
             do  
             {            
                  等待用戶添加打印紙          
             }  
             while(用戶沒有添加打印紙)        
        }      
    }    
}  

    運行時異常表示無法讓程序恢復運行的異常,導致這種異常的原因通常是由於執行了錯誤操作。一旦出現了錯誤操作,建議終止程序,因此Java編譯器不檢查這種異常。

    如果程序代碼中有錯誤,就可能導致運行時異常,如以下for語句的循環條件不正確,會導致ArrayIndexOutOfBoundsException:

 

public void method(int[] array)  
{  
    for (int i = 0; i <=array.length; i++)  
    {   
        // 當i的取值為array.length時,將拋出ArrayIndexOutOfBoundsException  
        array[i] = 1;  
    }  
}   

    只要對程序代碼做適當修改,就能避免數組下標越界異常:

public void method(int[] array)  
{  
    for (int i = 0; i <array.length; i++)  
    {   
        // 當i的取值為array.length時,將拋出ArrayIndexOutOfBoundsException  
        array[i] = 1;  
    }  
}   

    再例如對於以下代碼,如果變量m為null,訪問"m.name"會導致NullPointerException異常:

Monkey m=null;    
if(m!==null & m.name.equals("Tom"))  
{……}  

    只要對程序代碼做適當修改,就能避免NullPointerException異常:

Monkey m=null;    
if(m!==null && m.name.equals("Tom"))  
{……}  

    由此可見,運行時異常是應該盡量避免的,在程序調試階段,遇到這種異常時,正確的做法是改進程序的設計和實現方式,修改程序中的錯誤,從而避免這種異常。捕獲它並且使程序恢復運行並不是明智的辦法,因為即使程序恢復運行,可能會導致程序的業務邏輯錯亂,導致更嚴重的異常,或者得到錯誤的運行結果。

java什么情況下必須用throws拋出異常?
    在程序中拋出了非RuntimeException異常卻沒有對其處理(用try catch塊處理)的情況下,必須在方法頭throws該異常。

什么情況下需要自定義異常呢?

    通常情況下是程序運行狀態與用戶的預先定義的邏輯不符合,但程序並不能識別這種邏輯錯誤時需自定義異常。比如某個方法的參數只能接受0~9的數字,數字1除外,萬一用戶要是輸入了1,我們可以自定義一個異常來處理1這個意外,從而控制程序流程等。

什么情況下捕獲異常應該立即處理呢?

    比如說接收用戶輸入整型值,而用戶卻輸入了不能解析成整型的字符串,這會拋出異常,我們不應該往外拋,而應該立即處理之,提示用戶輸入合法的值,待用戶輸入合法值之后,接着往下執行程序。捕獲到異常之后一般處理辦法是輸出錯誤日志,或者給用戶一些提示。

[轉文]

    Exception異常分為:RuntimeException(運行時異常,也叫未檢查異常或不受檢查異常)和已檢查異常(或受檢查異常):

已檢查異常 是指程序員已經足夠小心的檢查了他的代碼,但是還是不能保證代碼不出現異常;如,程序要訪問某個文件,但訪問時文件不存在,這和程序本身沒有太大關系;再如,程序要進行網絡連接,但執行時沒有連接網線,這些問題都是已檢查異常。

未檢查異常 一般是由程序員沒有細心檢查代碼,而導致的如空指針異常、數組越界、類型轉換異常等都是由於程序員粗心大意造成的。這些異常是在編碼過程中是能夠避免的。

    看到此你需要思考:我們需要處理的到底是已檢查異常還是未檢查異常?如一幢大樓運行過程中被雷擊中,這肯定是已檢查異常,但運行過程中發現有個地方四周沒有窗戶和門,這就是未檢查異常,那到底我們需要針對哪個異常進行應急預案呢?當驗收大樓時肯定政府部門要檢查你的抗震級別,消防措施等,這些措施是你在修建時必須考慮,而且要求是強制執行的,那么這個要求就是必須處理的,如果不處理則編譯通不過。如果出現未檢查異常,那就只能加門或窗戶,即修改代碼了。

    從另外一個角度來講,已檢查異常(受檢查異常)就是受編譯器檢查的異常。

    運行時異常,屬於RuntimeException類及子類范圍的類(以及衍生類)都屬於運行時異常。

    受檢查異常,在Exception范圍內,除了運行時異常的類都是受檢查異常類,為checked exception

它們之間的區別在於:

例如在代碼中寫了 throw new Exception(); 和 throw new RuntimeException();  兩者都會在運行期間拋出異常!

(1)但是在編譯階段前者屬於拋出一個受檢查異常,要求對它進行顯式的try..catch捕獲處理或者向上一層方法拋出,否則在編譯期間就顯示錯誤!

(2)后者拋出是運行時異常,在編譯階段不予檢查,語法上不會顯示任何錯誤(throws處沒聲明不會出錯,但最好聲明)!

所以簡單的通過throw手動拋出受檢查異常和拋出運行時異常,前者要求顯式處理,后者不要求作出處理。

我以為的設計原則:

(1)受檢查異常如FileNotFoundException,編譯時期受檢查,提醒用戶try{}catch{}或者throw到上一層,當然你可以一直throw直至拋給虛擬機,然而這並不是好的方式,因為對於這個異常,我們是可以進行一些處理,挽救的,比如我們可以在捕獲到異常的時候,提醒用戶"找不到文件",用戶就可以根據這個信息,把相應文件放到指定位置,從而解決問題,並不需要終止程序,或者修改代碼。

(2)而對於非受檢查異常如ArrayIndexOutOfBoundsException(數組越界異常),編譯時期不提供錯誤檢查,我想是因為,針對這個錯誤,用戶是無能為力的,同樣程序員也是部分無能為力的,你不可能通過try{}catch{}去捕獲這個異常之后,再去增加數組容量。這時你所能做的,只能是去修改代碼,如修改數組容量,或換個自增的數據結構。這種運行時錯誤,只能通過在編譯階段,依靠程序員的小心謹慎來避免。


注意!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系我们删除。



 
粤ICP备14056181号  © 2014-2021 ITdaan.com