Java中的控制語句中異常處理語句:try-catch-finally,throw。
讓客戶滿意是我們工作的目標,不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:域名注冊、雅安服務(wù)器托管、營銷軟件、網(wǎng)站建設(shè)、阜城網(wǎng)站維護、網(wǎng)站推廣。
異常作用:在Java中,在默認情況下,異常會輸出一個錯誤信息,然后中止程序的執(zhí)行。為了更好地處理異常情況,程序開發(fā)人員通常會在程序中定義異常處理代碼塊來捕獲和處理異常。這樣,當異常情況發(fā)生時,一個代表該異常的對象會被創(chuàng)建,并在產(chǎn)生異常的方法中被引發(fā)。該方法可以選擇自己處理異常,也可以拋出該異常。
可以選擇三種方法來進行異常處理1對代碼塊用try..catch進行異常捕獲處理;
2在 該代碼的方法體外用throws進行拋出聲明,告知此方法的調(diào)用者這段代碼可能會出現(xiàn)這些異常,你需要謹慎處理。此時有兩種情況:
如果聲明拋出的異常是非運行時異常,此方法的調(diào)用者必須顯示地用try..catch塊進行捕獲或者繼續(xù)向上層拋出異常。
如果聲明拋出的異常是運行時異常,此方法的調(diào)用者可以選擇地進行異常捕獲處理。
3在代碼塊用throw手動拋出一個異常對象,此時也有兩種情況,跟2)中的類似:
如果拋出的異常對象是非運行時異常,此方法的調(diào)用者必須顯示地用try..catch塊進行捕獲或者繼續(xù)向上層拋出異常。
如果拋出的異常對象是運行時異常,此方法的調(diào)用者可以選擇地進行異常捕獲處理。
(如果最終將異常拋給main方法,則相當于交給jvm自動處理,此時jvm會簡單地打印異常信息)
常處理和設(shè)計的建議
1. 只在必要使用異常的地方才使用異常,不要用異常去控制程序的流程
2. 切忌使用空catch塊
3. 檢查異常和非檢查異常的選擇
4. 注意catch塊的順序
5. 不要將提供給用戶看的信息放在異常信息里
6. 避免多次在日志信息中記錄同一個異常
7. 異常處理盡量放在高層進行
8. 在finally中釋放資源
相信作為程序員的我們在對程序進行編譯過程中經(jīng)常會遇到錯誤,或者在運行過程中出現(xiàn)錯誤,在這里主要跟大家談?wù)劷?jīng)常遇到的一些異常與錯誤,以及解決辦法。
異常是指程序在編譯或運行過程出現(xiàn)的錯誤。
在java.lang包中Throwable包含了所有的異常。
Error (錯誤) 和Exception(異常)
(1)Error(錯誤)
一旦發(fā)生無法修復(fù),但可以避免發(fā)生。
常見錯誤類:
IOError:I/O錯誤,當發(fā)生嚴重的I/O錯誤時,拋出此錯誤。
VirtualMachineError?:虛擬機錯誤,當 Java 虛擬機崩潰或用盡了它繼續(xù)操作所需的資源時,拋出該錯誤。
StackOverflowError:棧內(nèi)存滿了,當應(yīng)用程序遞歸太深而發(fā)生堆棧溢出時,拋出該錯誤。
OutofMemoryError:堆內(nèi)存滿了,因為內(nèi)存溢出或沒有可用的內(nèi)存提供給垃圾回收器時,Java 虛擬機無法分配一個對象,這時拋出該異常。
以上是一些常見的錯誤,在Error類中還有一些別的錯誤(參照文件Java.lang.Throwable.Error).
(2)Exception(異常)
一旦發(fā)生,可以捕獲并處理,不會導(dǎo)致程序終止,有時可以避免有時無法避免。
異常的分類:
1.編譯時異常(需要強制處理)?????? 2.運行時異常(不需要強制處理)
常見的異常有:
IOException:輸入輸出流異常
FileNotFoundException:文件找不到的異常
ClassNotFoundException:類找不到的異常
DataFormatException:數(shù)據(jù)格式化異常
NoSuchFieldException:沒有匹配的屬性異常
NoSuchMethodException:沒有匹配的方法異常
SQLException:數(shù)據(jù)庫操作異常
TimeoutException:執(zhí)行超時異常
常見的運行時異常:
RuntimeException:運行時異常
NullPointerException:空指針異常
ArrayIndexOutofBoundsException:數(shù)組越界異
ClassCastException:類型轉(zhuǎn)換異常
IllegalArgumentException:非法的參數(shù)異常
InputMismatchException:輸入不匹配
以上是常見的一些異常,另外還有別的異常,參見文件:Java.lang.Throwable.Exception
既然我們常常會遇到一些異常,那我們?nèi)绾蝸硖幚磉@些異常就是一個急需解決的事情。
(1) 如何處理編譯時異常?
方法一:將需要處理的代碼塊放在一個try...catch...中
try{
//需要處理異常的代碼
}catch(XXXException ef){
ef.printStackTrace();
}
我們方法一就是要將我們不確定的代碼放入try......catch中,先進行try一下,如果沒有異常,則不會觸發(fā)catch,沒有輸出,一旦出現(xiàn)異常,那么catch就會工作,在catch中捕獲異常信息,根據(jù)異常信息進行補救措施。
如以下代碼:
方法二:在出現(xiàn)異常的方法上直接向上拋出異常,throws
void ff() throws XXXException{
}
將出現(xiàn)的異常的代碼中,放入如上的方法中,就會將異常拋給該方法的上一級,在主函數(shù)上繼續(xù)向上拋,最終拋給JVM java虛擬機,讓JVM來解決該問題。
如代碼:
注意:在catch和throws的時候如果不確定是什么異常,就直接寫一個Exception.
(2) 如何處理運行時異常?
1.一般情況下,運行時異常是不用處理的?
2.在某些情況下,如果對發(fā)生異常的結(jié)果進行處理,也可以對運行時異常進行try...catch...
以上就是一些我們處理編譯時異常和運行時異常的方法。
在程序出現(xiàn)異常時,有時候我們可以自定義異常,以便我們能夠發(fā)現(xiàn)是什么異常。
那么如何自定義異常??
1.當運行時,程序出現(xiàn)意外,可以拋出異常對象來結(jié)束程序
如:
//拋出運行時異常對象
RuntimeException ef = new RuntimeException("下標越界!index:"+index+" ,size:"+size());
throw ef;
2.對于編譯時異常,同樣可以拋出異常對象
但在方法定義時候必須加上throws
如:
public void test(int t) throws Exception{
if (t 0 || t 100) {
Exception ef = new Exception("數(shù)據(jù)錯誤");
throw ef;
}
}
例如:
運行結(jié)果:
從結(jié)果可以看出,我們在輸入數(shù)據(jù)的時候出現(xiàn)錯誤,這樣通過自定義異常能夠讓我們更直接快速的找到運行或編譯時的異常。
在上述中我們分別提到了三種throw,分別是Throwable,Throws以及throw,那么到底三者有什么區(qū)別?
Throwable:是指在在Java.lang包中的一個類,其包含了所有的異常和錯誤,其中類Error和Exception 是它
的子類。
Thows:是指在解決編譯時異常,將方法中異常拋給上一級,在方法后面要加Throw Exception來進行拋。
throw:是指在自定義異常時,如果方法出現(xiàn)異常,那么將作為引用方法的對象拋出。即拋出異常。
希望對您有所幫助!~
1. 異常機制
異常機制指當程序出現(xiàn)錯誤程序何處理具體來說異常機制提供了程序退出安全通道當出現(xiàn)錯誤程序執(zhí)行流程發(fā)生改變程序控制權(quán)轉(zhuǎn)移異常處理器
傳統(tǒng)處理異常辦法函數(shù)返回特殊結(jié)來表示出現(xiàn)異常(通常特殊結(jié)大家約定俗稱)調(diào)用該函數(shù)程序負責檢查并分析函數(shù)返回結(jié)樣做有下弊端:例函數(shù)返回-1代表出現(xiàn)異常函數(shù)確實要返回-1正確值時會出現(xiàn)混淆;讀性降低程序代碼與處理異常代碼混爹起;由調(diào)用函數(shù)程序來分析錯誤要求客戶程序員對庫函數(shù)有深了解
異常處理流程:
① 遇錯誤方法立即結(jié)束并返回值;同時拋出異常對象
② 調(diào)用該方法程序也會繼續(xù)執(zhí)行下去而搜索處理該異常異常處理器并執(zhí)行其代碼
2 異常分類
異常分類:
① 異常繼承結(jié)構(gòu):基類ThrowableError和Exception繼承ThrowableRuntimeException和IOException等繼承Exception具體RuntimeException繼承RuntimeException
② Error和RuntimeException及其子類成未檢查異常(unchecked)其異常成已檢查異常(checked)
每類型異常特點
Error體系 :
Error類體系描述了Java運行系統(tǒng)內(nèi)部錯誤及資源耗盡情形應(yīng)用程序應(yīng)該拋出種類型對象(般由虛擬機拋出)出現(xiàn)種錯誤除了盡力使程序安全退出外其方面無能力所進行程序設(shè)計時應(yīng)該更關(guān)注Exception體系
Exception體系包括RuntimeException體系和其非RuntimeException體系 :
① RuntimeException:RuntimeException體系包括錯誤類型轉(zhuǎn)換、數(shù)組越界訪問和試圖訪問空指針等等處理RuntimeException原則:出現(xiàn)RuntimeException定程序員錯誤例通過檢查數(shù)組下標和數(shù)組邊界來避免數(shù)組越界訪問異常
②其非RuntimeException(IOException等等):類異常般外部錯誤例試圖從文件尾讀取數(shù)據(jù)等并程序本身錯誤而應(yīng)用環(huán)境出現(xiàn)外部錯誤
與C++異常分類同 :
① JavaRuntimeException類名起并恰當因任何異常都運行時出現(xiàn)(編譯時出現(xiàn)錯誤并異常換句說異常了解決程序運行時出現(xiàn)錯誤)
② C++logic_error與JavaRuntimeException等價而runtime_error與Java非RuntimeException類型異常等價
3 異常使用方法
聲明方法拋出異常
① 語法:throws(略)
② 要聲明方法拋出異常
方法否拋出異常與方法返回值類型樣重要假設(shè)方法拋出異常確沒有聲明該方法拋出異常客戶程序員調(diào)用方法而且用編寫處理異常代碼旦出現(xiàn)異常異常沒有合適異常控制器來解決
③ 拋出異常定已檢查異常
RuntimeException與Error任何代碼產(chǎn)生們需要由程序員顯示拋出旦出現(xiàn)錯誤相應(yīng)異常會被自動拋出而已檢查異常由程序員拋出分兩種情況:客戶程序員調(diào)用會拋出異常庫函數(shù)(庫函數(shù)異常由庫程序員拋出);客戶程序員自己使用throw語句拋出異常遇Error程序員般無能力;遇RuntimeException定程序存邏輯錯誤要對程序進行修改(相當于調(diào)試種方法);只有已檢查異常才程序員所關(guān)心程序應(yīng)該且僅應(yīng)該拋出或處理已檢查異常
注意:覆蓋父類某方法子類方法能拋出比父類方法更多異常所有時設(shè)計父類方法時會聲明拋出異常實際實現(xiàn)方法代碼卻并拋出異常樣做目了方便子類方法覆蓋父類方法時拋出異常
何拋出異常
① 語法:throw(略)
② 拋出異常對于異常對象真正有用信息時異常對象類型而異常對象本身毫無意義比異常對象類型ClassCastException類名唯有用信息所選擇拋出異常時關(guān)鍵選擇異常類名能夠明確說明異常情況類
③ 異常對象通常有兩種構(gòu)造函數(shù):種無參數(shù)構(gòu)造函數(shù);另種帶字符串構(gòu)造函數(shù)字符串作異常對象除了類型名外額外說明
④ 創(chuàng)建自己異常:當Java內(nèi)置異常都能明確說明異常情況時候需要創(chuàng)建自己異常需要注意唯有用類型名信息所要異常類設(shè)計上花費精力
捕獲異常
異常沒有被處理對于非圖形界面程序而言該程序會被止并輸出異常信息;對于圖形界面程序也會輸出異常信息程序并止而返回用錯誤頁面
語法:try、catch和finally(略)控制器模塊必須緊接try塊面若擲出異常異常控制機制會搜尋參數(shù)與異常類型相符第控制器隨會進入catch 從句并認異常已得控制旦catch 從句結(jié)束對控制器搜索也會停止
捕獲多異常(注意語法與捕獲順序)(略)
finally用法與異常處理流程(略)
異常處理做對于Java來說由于有了垃圾收集所異常處理并需要回收內(nèi)存依有些資源需要程序員來收集比文件、網(wǎng)絡(luò)連接和圖片等資源
應(yīng)該聲明方法拋出異常還方法捕獲異常原則:捕捉并處理哪些知道何處理異常而傳遞哪些知道何處理異常
再次拋出異常
①要再次拋出異常 本級只能處理部分內(nèi)容有些處理需要更高級環(huán)境完成所應(yīng)該再次拋出異常樣使每級異常處理器處理能夠處理異常
②異常處理流程 :對應(yīng)與同try塊catch塊被忽略拋出異常進入更高級
4 關(guān)于異常其問題
① 過度使用異常 :首先使用異常方便所程序員般再愿意編寫處理錯誤代碼而僅僅簡簡單單拋出異常樣做對對于完全已知錯誤應(yīng)該編寫處理種錯誤代碼增加程序魯棒性另外異常機制效率差
② 異常與普通錯誤區(qū)分開:對于普通完全致錯誤應(yīng)該編寫處理種錯誤代碼增加程序魯棒性只有外部能確定和預(yù)知運行時錯誤才需要使用異常
③ 異常對象包含信息 :般情況下異常對象唯有用信息類型信息使用異常帶字符串構(gòu)造函數(shù)時字符串還作額外信息調(diào)用異常對象getMessage()、toString()或者printStackTrace()方法分別得異常對象額外信息、類名和調(diào)用堆棧信息并且種包含信息前種超集
5 常見異常
算術(shù)異常類:ArithmeticExecption
空指針異常類:NullPointerException
類型強制轉(zhuǎn)換異常:ClassCastException
數(shù)組負下標異常:NegativeArrayException
數(shù)組下標越界異常:ArrayIndexOutOfBoundsException
違背安全原則異常:SecturityException
文件已結(jié)束異常:EOFException
文件未找異常:FileNotFoundException
字符串轉(zhuǎn)換數(shù)字異常:NumberFormatException
操作數(shù)據(jù)庫異常:SQLException
輸入輸出異常:IOException
方法未找異常:NoSuchMethodException
1.檢查型異常,這樣的異常繼承于Excetpion,就是在編譯期間需要檢查,如果該異常被throw,那么在該異常所在的method后必須顯示的throws,調(diào)用該method的地方也必須捕獲該異常,否則編譯器會拋出異常.ejb里的RemoteException是一個這樣的異常.來源:考試大
2.運行時異常,就是在運行期間系統(tǒng)出現(xiàn)的異常,該類異常繼承于RuntimeException,該類異常在編譯時系統(tǒng)不進行檢查,如NullPointerExcetpion,NumberFormatException.
3.系統(tǒng)錯誤,一般是JVM出現(xiàn)異常時拋出的異常,如OutofMemoryError,這樣的異常在J2EE開發(fā)中是不用關(guān)心的.考試大論壇
在J2EE開發(fā)中,檢查型異常被濫用以至于過一段時間程序員自己都看不懂拋出這樣的異常,.里面封裝的這些錯誤信息是干什么用的,更可怕的是有好多有用的信息找不到了.比如SQLException和RemoteException這樣的異常我們沒必要再進行封裝,這樣的異常只對我們調(diào)試程序有用,而對客戶來說它就是一個”系統(tǒng)錯誤”而已.異常處理有一個簡單的原則,你什么時候需要封裝自己的檢查型異常?就是你很清楚自己拋出這個異常的用途時,比如用戶輸入用戶名和密碼要登錄,但用戶名和密碼不匹配,你就要定義一個檢查型異常,客戶端通過捕獲該異常,然后把相應(yīng)的錯誤信息反饋給客戶.而其它的自己未預(yù)期的錯誤或者異常比如SQLException,只需封裝到EJBException中,ejb container會把它的信息追加到RemoteException里,這樣客戶端捕獲RemoteException后把它寫到系統(tǒng)日志里,就很容易進行調(diào)試。
Java 異常的處理
在 Java 應(yīng)用程序中,對異常的處理有兩種方式:處理異常和聲明異常。
處理異常:try、catch 和 finally
若要捕獲異常,則必須在代碼中添加異常處理器塊。這種 Java 結(jié)構(gòu)可能包含 3 個部分,
都有 Java 關(guān)鍵字。下面的例子中使用了 try-catch-finally 代碼結(jié)構(gòu)。
import java.io.*; public class EchoInputTryCatchFinally { public static void main(String args[]){ System.out.println(”Enter text to echo:”); InputStreamReader isr = new InputStreamReader(System.in); BufferedReader inputReader = new BufferedReader(isr); try{ String inputLine = inputReader.readLine(); System.out.println(”Read:” + inputLine); } catch(IOException exc){ System.out.println(”Exception encountered: ” + exc); } finally{ System.out.println(”End. “); } } 其中:
try 塊:將一個或者多個語句放入 try 時,則表示這些語句可能拋出異常。編譯器知道可能要發(fā)生異常,于是用一個特殊結(jié)構(gòu)評估塊內(nèi)所有語句。
catch 塊:當問題出現(xiàn)時,一種選擇是定義代碼塊來處理問題,catch 塊的目的便在于此。catch 塊是 try 塊所產(chǎn)生異常的接收者。基本原理是:一旦生成異常,則 try 塊的執(zhí)行中止,JVM 將查找相應(yīng)的 JVM。
finally 塊:還可以定義 finally 塊,無論運行 try 塊代碼的結(jié)果如何,該塊里面的代碼一定運行。在常見的所有環(huán)境中,finally 塊都將運行。無論 try 塊是否運行完,無論是否產(chǎn)生異常,也無論是否在 catch 塊中得到處理,finally 塊都將執(zhí)行。
try-catch-finally 規(guī)則:
必須在 try 之后添加 catch 或 finally 塊。try 塊后可同時接 catch 和 finally 塊,但至少有一個塊。
必須遵循塊順序:若代碼同時使用 catch 和 finally 塊,則必須將 catch 塊放在 try 塊之后。
catch 塊與相應(yīng)的異常類的類型相關(guān)。
一個 try 塊可能有多個 catch 塊。若如此,則執(zhí)行第一個匹配塊。
可嵌套 try-catch-finally 結(jié)構(gòu)。
在 try-catch-finally 結(jié)構(gòu)中,可重新拋出異常。
除了下列情況,總將執(zhí)行 finally 做為結(jié)束:JVM 過早終止(調(diào)用 System.exit(int));在 finally 塊中拋出一個未處理的異常;計算機斷電、失火、或遭遇病毒攻擊。
聲明異常
若要聲明異常,則必須將其添加到方法簽名塊的結(jié)束位置。下面是一個實例:
public void errorProneMethod(int input) throws java.io.IOException { //Code for the method,including one or more method //calls that may produce an IOException } 這樣,聲明的異常將傳給方法調(diào)用者,而且也通知了編譯器:該方法的任何調(diào)用者必須遵守處理或聲明規(guī)則。聲明異常的規(guī)則如下:
必須聲明方法可拋出的任何可檢測異常(checked exception)。
非檢測性異常(unchecked exception)不是必須的,可聲明,也可不聲明。
調(diào)用方法必須遵循任何可檢測異常的處理和聲明規(guī)則。若覆蓋一個方法,則不能聲明與覆蓋方法不同的異常。聲明的任何異常必須是被覆蓋方法所聲明異常的同類或子類。