異常:異常是程序正常執(zhí)行過程中出現(xiàn)的不正常的情況。
異常捕獲的順序是怎樣的呢?當(dāng)一個異常發(fā)生或拋出。? ? 那么正常的程序執(zhí)行序列將被終
止,程序?qū)Ξ惓_M行處理,我們稱之為拋出異常被捕獲。 JAVA 中通過使用 try-catch 語句把可能拋出異常的語句包起來。
怎樣捕獲一個異常呢。
a、 把正常運行的代碼放在 try 塊里。
b、 如果程序中出現(xiàn)了異常就把異常拋出在? ? catch 中,如果 catch中能捕獲拋出的異常。
那么就會進行處理。處理的代碼寫在 catch 塊中。
try 程序塊里面的語句是按順序執(zhí)行的語句知識點:1、? ? 什么是異常。異常是程序正常執(zhí)行過程中出現(xiàn)的不正常的情況。例如:? ? 人在成長過程中,是個正常的執(zhí)行過程,但成長過程中會經(jīng)常生病,這就是異常。為了避免這種不正 常的情況,我們會采取一系列措施,比如:從小鍛煉身體,吃新鮮干凈的食物,營養(yǎng)合 理的搭配,以增強我們的體質(zhì)。提高抗病能力。程序我們?yōu)榱颂岣咚\行時的健壯性, 我們也得采用一些措施。那么怎么提高程序的健壯性呢? JAVA 程序中我通過異常的捕 獲來增加程序的健壯性。2、? ? 異常捕獲的順序是怎樣的呢?當(dāng)一個異常發(fā)生或拋出。? ? 那么正常的程序執(zhí)行序列將被終止,程序?qū)Ξ惓_M行處理,我們稱之為拋出異常被捕獲。 JAVA 中通過使用 try-catch 語句把可能拋出異常的語句包起來。例如:前面講到資源文件類 Properties 類在進行文 件加載時,使用以下語句捕捉異常。try{Properties pro=new Properties();Pro.load(new FileInputStream( “c:/abc.properties ”));}catch(IOException e){System.out.println(e);}3、? ? 異常的類型是怎樣的呢?
所有異常類的超類是 Throwable 。在 Throwable 下有兩個子類,一個是 Error ,另一個是 Exception 。 Error 是錯誤,程序員無法控制, Exception 是異常,程序員可以通過異常捕獲加 以控制。例如: 電腦運行中中毒了, 我們可以通過殺毒軟件來處理,處理完了以后可以繼續(xù) 使用, 這叫異常,我們可以控制。但電腦出現(xiàn)了藍屏或死機的時候,我們就不能進行任何操 作了。這就是錯誤,我們無法控制。4、? ? 程序中異常是怎么發(fā)生的呢?
請輸入“年齡 ” );
showInputDialog 得到的是個字符串。
String inputStr = JOptionPane.showInputDialog(null, int age = Integer.parseInt(inputStr); 以上代碼要求用戶輸入年齡,年齡是個數(shù)字。但通過
所以我們需要 Integer.parseInt(inputStr) ,將字符串轉(zhuǎn)成數(shù)字。這個時候,如果用戶輸入的不 是 一 個數(shù) 字 型的 字 符串 , 而 是 一個 非 數(shù)字 的字 符 串( 如 字母 、符 號 ), 在 進行 Integer.parseInt(inputStr) 轉(zhuǎn)化是就會發(fā)生一個異常。如果我們不對它作任何處理,程序就有 可能因此終止掉。5、 怎樣捕獲一個異常呢。a、 把正常運行的代碼放在 try 塊里。b、 如果程序中出現(xiàn)了異常就把異常拋出在? ? catch 中,如果 catch中能捕獲拋出的異常。那么就會進行處理。處理的代碼寫在 catch 塊中。try 程序塊里面的語句是按順序執(zhí)行的語句當(dāng) try 程序塊里面的語句拋出一個異常的時候,程序的控制轉(zhuǎn)向了相匹配的? ? catch 程序塊, catch 程序塊里面的語句被執(zhí)行。當(dāng)異常發(fā)生后, 程序執(zhí)行將忽略 try 程序塊中剩余的語句, 繼續(xù)執(zhí)行程序塊后面的語句。如果在 面的語句try 程序塊中沒有拋出異常,那么 catch 塊將被忽略。程序?qū)⒗^續(xù)執(zhí)行 try-catch例如:try{System.out.println( int x=4/0;//2開始 ”);//1System.out.println(}catch(Exception e){System.out.println(}System.out.println( 這是發(fā)生異常的情況,在執(zhí)行 ”);//3發(fā)生異常 ”);//4異常處理外部 ”);try 塊里順序執(zhí)行,先打出“開始” ,沒有異常繼續(xù)執(zhí)行,當(dāng) 執(zhí)行到第 2行時,因為 0 不能做除數(shù),所以會發(fā)生一個算術(shù)異常。這個時候就會跳過 try 塊 里剩下的語句轉(zhuǎn)去執(zhí)行 catch 塊中的內(nèi)容。 所以第 3行就不能執(zhí)行。 跳到 catch 塊中執(zhí)行第 4
句,打出“發(fā)生異常” 。執(zhí)行完以后接著往下順序執(zhí)行。打出第 5 行“異常處理外部” 。try{System.out.println( “開始 ”);//1int x=4/2;//2System.out.println( “執(zhí)行 ”);//3}catch(Exception e){System.out.println( “發(fā)生異常 ”);//4}System.out.println( “異常處理外部 ”);這是正常情況,在 try 塊里順序執(zhí)行,先打出“開始” ,沒有異常繼續(xù)執(zhí)行,當(dāng)執(zhí)行到 第 2 行時,得到 x 的值為 2 ,不會有異常。這個時候繼續(xù)執(zhí)行到第? ? 3 行,打出“執(zhí)行” 。因為在 try 塊中沒有任何異常,執(zhí)行完以后接著往下順序執(zhí)行。打出第 5 行“異常處理外部” 。在 Throwable 類中有兩個方法,可以用于獲取拋出異常的信息getMessageprintStackTrace6、 拋出異常 在一個 try-catch 語句中,當(dāng)有多個 catch 塊的時候,它們被順序檢查在檢查過程中,注意異常的匹配關(guān)系是很重要的當(dāng)一個異常被拋出, 與它相匹配的 catch塊被執(zhí)行, 其它的 catch 塊,就被忽略掉不再執(zhí) 行如果沒有 catch 塊匹配拋出的異常,那么系統(tǒng)會在堆棧中搜索,找到一個匹配的捕獲方 法。如果仍然沒有找到,那么系統(tǒng)將處理拋出異常什么叫異常和 catch 塊相匹配:1、拋出的異常和捕捉的異常是同一個類2、拋出的異常是捕捉異常的子類3、多個 catch 塊中 如果捕捉的異常之間有繼承關(guān)系 那么不要把父類放在子類之 前(這種做法也不被允許)4、盡量不要偷懶 使用具體異常類而不要使用 Exception例如 :try {int [] a= new int [4] ;System. out .println(a[6]);//1int i=3/0;//2
} catch (java.lang.ArithmeticException e){//? ? 捕獲第 2行異常System. out .println( "算術(shù)錯誤 ");}catch (java.lang.ArrayIndexOutOfBoundsException e){ //? ? 捕獲第 1行異常System. out .println( "數(shù)組下標(biāo)越界 ");}不同的異常由不同的 catch 塊進行捕獲。發(fā)生異常時由相應(yīng)的 catch 塊進行處理。Catch 塊中怎么捕獲異常?try{int i=3/0;}catch(java.lang.ArithmeticException e){// 拋出異常和捕獲異常是同一個類 System.out.println(" 算術(shù)錯誤 ");}try{ int i=3/0;}catch(java.lang.Exception e){// 拋出異常是捕獲異常的子類 System.out.println(" 算術(shù)錯誤 ");try {int [] a= new int [4] ;System. out .println(a[6]);} catch (java.lang. Exception e){System. out .println( "發(fā)生異常 ");}catch (java.lang.ArrayIndexOutOfBoundsException e){System. out .println( "數(shù)組下標(biāo)越界 ");}這種方 式不被 允許,因為 catch 塊前一個異常 Exception 是后一 個異常 ArrayIndexOutOfBoundsException 的父類。所以有異常前一個異常 catch 塊都捕 獲了。后一個 catch 塊永遠不會被執(zhí)行。編譯會出錯。try {int [] a= new int [4] ;System. out .println(a[6]);
} catch (java.lang.ArrayIndexOutOfBoundsException e){System. out .println( "數(shù)組下標(biāo)越界 ");}catch (java.lang.Exception e){ System. out .println( "發(fā)生異常 ");}這種方式允許。如果有數(shù)組下標(biāo)越界異常由第一個 catch 塊處理。如果有其它異常 由第二個 catch 塊處理。7、如果有一塊代碼不管是否發(fā)生異常拋出都要被執(zhí)行,我們使用關(guān)鍵字 finally 這樣的機 制有助于我們進行系統(tǒng)資源的回收。比如:在數(shù)據(jù)庫操作時,如果發(fā)生了異常,那么數(shù) 據(jù)庫連接就可能不會關(guān)閉,而一直長駐內(nèi)存。在進行 IO 文件讀取和寫入時,如果發(fā)生 了異常就可能流不會關(guān)閉。所以使用 finally 可以解決這樣的問題。Try{}catch(){}finally{
這樣的結(jié)構(gòu)可以用警察抓小偷來說明,警察抓小偷,如果小偷守法(沒有異常)則警察 就不會抓他,如果小偷違法(發(fā)生異常) 不管抓沒有抓到,警察工資照拿。
finally 內(nèi)容”
因為發(fā)生異常,所以 catch 里內(nèi)容執(zhí)行。執(zhí)行結(jié)果是“發(fā)生異?!焙汀?、 關(guān)于 finally 的問題 大家都知道 return 是跳出方法的語句, 如果在 try 里有 return 語句那么 finally 里的 內(nèi)容會不會執(zhí)行呢?答案是會的。會在 return 語句之前執(zhí)行,執(zhí)行完 finally 語句之后, return 語句再執(zhí)行。public void change(){try {int x=9/0;//1 return;} catch (Exception e){System. out .println( "發(fā)生異常 ");}finally {System. out .println( "finally 內(nèi)容 ");}System. out .println( " 異常外部內(nèi)容 " );}該代碼發(fā)生了異常。 所以第一行代碼以下語句會被忽略, 所以 return 語句不會執(zhí)行 該代碼執(zhí)行結(jié)果為“發(fā)生異?!?、“ finally 內(nèi)容”、“異常外部內(nèi)容”public void change(){ try {int x=9/4;System. out .println( "正常執(zhí)行 "); return;} catch (Exception e){System. out .println( "發(fā)生異常 ");}finally {System. out .println( "finally 內(nèi)容 ");}System. out .println( " 異常外部內(nèi)容 " );該代碼沒有發(fā)生異常。順序執(zhí)行。先打“正常執(zhí)行”,遇到 return 語句后,在返回 前,先執(zhí)行“ finally 內(nèi)容”再做返回。因為方法已經(jīng)跳出,所以“異常外部內(nèi)容” 不會執(zhí)行。
finally 在任何時候都會執(zhí)行,但有一個例外那就是程序終止時,不會執(zhí)行 public void change(){try {
“正常執(zhí)行 ”);"發(fā)生異常 ");"finally 內(nèi)容 ");" 異常外部內(nèi)容 " );
int x=9/4;System.out.println(System.exit(0);} catch (Exception e){System. out .println( } finally {System. out .println( }System. out .println(因為沒有異常, 所以“正常執(zhí)行” 會打出來, 但這個時候程序終止運行。 所以 finally 內(nèi)容不會打出來。9、關(guān)于異常對象異常也是一個對象。它是 Exception 類或子類的一個對象public void change(){try {int x=9/0;//1} catch (Exception e)//2{System. out .println( "發(fā)生異常 ");}}在執(zhí)行到第 1 行時,發(fā)生了異常。這時候會產(chǎn)生一個和異常相匹配的異常對象。然 后在第 2 行時,用一個 Exception e 的一個變量去指向它。這個時候,如果人為的拋出一個異常也可以達到相同的效果。這就是 throw 語句。將顯示的產(chǎn)生一個異常對象,并做拋出。語法如下:throw 異常對象 (throw new Exception()) 。
10、傳播異常 一個方法可以拋出異常,這樣的話,在方法里我們就不用去捕獲方法里可能發(fā)生的相關(guān) 異常。那么誰去處理這個異常呢?由調(diào)用該方法的代碼塊去處理。那么怎么樣在方法里 拋出異常呢?我們需要修改方法的聲明頭,聲明方法傳播的異常類型我們使用關(guān)鍵字 throws 來完成這個聲明例: void c( ) throws Exception {}void d( ) throws Exception {}在 d() 方法中拋出了 Exception 異常,但在方法體里卻可以不產(chǎn)生異常對象。就象要開槍 先瞄準(zhǔn),但瞄準(zhǔn)后可以不開槍。11、異常的類型異常會為編譯期異常和運行期異常。 (或檢查異常和非檢查異常)其中運行期異常是 RuntionException 類和它的子類。除此之外都是編譯期異常。編譯期異常是我們必須要捕獲的,而運行期異常卻可以捕獲,也可以不捕獲。就象警察 一樣,大案和要案是必須要立案偵破的,而小偷小摸的毛賊,可以抓也可以不抓。編譯異常我們必須要處理,要么用 try-catch 包圍,要么做方法拋出。如果一個方法拋出編譯期異常,那么調(diào)用該方法時,必須處理,如果拋出運行期異常, 那么調(diào)用該方法時,可處理可不處理。void C( ) throws Exception {}void a(){try{ c();}catch(Exception e){System.out.println( “異常 ”);}
public class TException{public static void main(String[] args){TException te = new TException();te.throwException();//1te.throwAException();//2te.throwCException();//3te.throwDException();//4}public void throwAException() throws Throwable{}public void throwCExcetion() throws Exception{}public void throwException() throws MyException{}public void throwDException() throws MyCException{}}class MyCException extends Exception{public MyCException(){}public MyCException(String msg){super(msg);}}class MyException extends RuntimeException{public MyException(){}public MyException(String msg){super(msg);}}代碼分析:在 main 方法里分別調(diào)用了四個方法。其中第 1 行代碼調(diào)用 throwException 方法。該方 法拋出 MyException 異常。而 MyException 是 RuntimeException 的子類,所以可以不處 理。不會發(fā)生編譯錯誤。 第 2行代碼調(diào)用 throwAException 方法,該方法拋出 Throwable 。 這是所有異常和錯誤的超類,包含編譯期異常,所以必須處理。直接寫的話,編譯會出 錯。怎樣捕獲一個異常呢。
a、 把正常運行的代碼放在 try 塊里。
b、 如果程序中出現(xiàn)了異常就把異常拋出在? ? catch 中,如果 catch中能捕獲拋出的異常。
那么就會進行處理。處理的代碼寫在 catch 塊中。
try 程序塊里面的語句是按順序執(zhí)行的語句當(dāng) try 程序塊里面的語句拋出一個異常的時候,程序的控制轉(zhuǎn)向了相匹配的? ? catch 程序塊, catch 程序塊里面的語句被執(zhí)行。當(dāng)異常發(fā)生后, 程序執(zhí)行將忽略 try 程序塊中剩余的語句, 繼續(xù)執(zhí)行程序塊后面的語句。如果在 面的語句
try 程序塊中沒有拋出異常,那么 catch 塊將被忽略。程序?qū)⒗^續(xù)執(zhí)行 try-catch