1.異常的概念
java的異常指的是運(yùn)行期出現(xiàn)的錯(cuò)誤,觀察錯(cuò)誤的名字和行號(hào)最重要
Java異常是Java提供的用于處理程序中錯(cuò)誤的一種機(jī)制。
所謂錯(cuò)誤是指在程序運(yùn)行的過程中發(fā)生的一些異常事件(如:除以0溢出,數(shù)組下標(biāo)越界,所要讀取的文件不存在)。
設(shè)計(jì)良好的程序應(yīng)該在異常發(fā)生時(shí)提供處理這些錯(cuò)誤的方法,使得程序不會(huì)因?yàn)楫惓5陌l(fā)生而阻斷或產(chǎn)生不可預(yù)見的結(jié)果。
Java程序的執(zhí)行過程中如出現(xiàn)異常事件,可以生成一個(gè)異常類對(duì)象,該異常對(duì)象封裝了異常事件的信息并將被提交給Java運(yùn)行時(shí)系統(tǒng),這個(gè)過程叫做拋出異常。
當(dāng)Java運(yùn)行時(shí)系統(tǒng)接收到異常對(duì)象時(shí),會(huì)尋找能處理這一異常的代碼并把當(dāng)前異常對(duì)象交給其處理,這一過程稱為捕獲異常。
public void someMethod() { throws SomeException {//聲明該方法可能拋出的異常 if(someCondition()) { throw new SomeException("錯(cuò)誤原因"); //構(gòu)造并拋出異常對(duì)象 } }}try{ //調(diào)用該方法是試圖捕捉異常 someMethod();}catch(SomeExceptione){ //定義處理異常的代碼//異常處理代碼;}捕獲異常:
public static void main(String[] array) { try { System.out.PRintln(2 / 0); } catch (ArithmeticException a) { System.out.println("系統(tǒng)正在維護(hù),請(qǐng)稍候……"); a.printStackTrace(); } }結(jié)果是:
系統(tǒng)正在維護(hù),請(qǐng)稍候……java.lang.ArithmeticException: / by zero at Test1.Test.main(Test.java:7)
2.異常的分類
throwable:可被拋出的
error:系統(tǒng)的錯(cuò)誤,處理不了的
exception:能夠處理的錯(cuò)誤
runtimeException:經(jīng)常出的錯(cuò)誤,可以捕獲也可以不捕獲其他類Exception:必須要捕獲
RuntimeException異常:
void m(int i) throws ArithmeticException { if(i==0) throw newArithmeticException("被除數(shù)為0"); } //聲明m方法Test te = new Test();te.m(0);第一種沒有捕獲錯(cuò)誤,程序也可以執(zhí)行結(jié)果是:
Exception in thread "main" java.lang.ArithmeticException:被除數(shù)為0 at Test1.Test.m(Test.java:67) at Test1.Test.main(Test.java:25)
第二種捕獲錯(cuò)誤:
try { newTest().m(0); } catch (ArithmeticExceptionae) { ae.printStackTrace(); System.out.println("出錯(cuò)了"); } }
結(jié)果是:
出錯(cuò)了java.lang.ArithmeticException: 被除數(shù)為0 at Test1.Test.m(Test.java:67) at Test1.Test.main(Test.java:29)Exception的其他錯(cuò)誤:
FileInputStream in = null; try{ in=new FileInputStream("myfile.txt"); int b; b=in.read(); while(b!=-1){ System.out.print((char)b); b=in.read(); } }catch(FileNotFoundException e){ e.printStackTrace(); } catch(IOException e){ System.out.println(e.getMessage()); }結(jié)果是:java.io.FileNotFoundException: myfile.txt (系統(tǒng)找不到指定的文件。) at java.io.FileInputStream.open(NativeMethod) at java.io.FileInputStream.(Unknown Source) at java.io.FileInputStream.(Unknown Source) at Test1.Test.main(Test.java:41)Exception in thread "main" java.lang.NullPointerException at Test1.Test.main(Test.java:58)5.finally語句
try代碼段包含可能產(chǎn)生異常的代碼,后跟有一個(gè)或多個(gè)catch代碼段。每個(gè)catch代碼段聲明其能處理的一種特定類型的異常并提供處理方法,當(dāng)異常發(fā)生時(shí)程序會(huì)終止當(dāng)前的流程,根據(jù)獲取的異常的類型去執(zhí)行相應(yīng)的catch代碼段。
finally段的代碼無論try中的代碼是否發(fā)生異常都有執(zhí)行,有異常時(shí)運(yùn)行catch后在執(zhí)行finally中的語句
try{ //可能拋出異常的語句
}catch(SomeException1 e){
……
}catch(SomeException2 e){
……
}finally{
……
}
在catch語句塊中可以使用e這個(gè)對(duì)象的一些方法獲取異常事件發(fā)生的信息。
如:getMessage()方法,用來得到有關(guān)異常事件的信息
printStackTrace()方法,用來跟蹤異常事件發(fā)生時(shí)執(zhí)行堆棧的內(nèi)容
finally語句:
finally語句為異常處理提供一個(gè)統(tǒng)一的出口,使得在控制流程轉(zhuǎn)到程序的其他部分以前,能夠?qū)Τ绦虻臓顟B(tài)作統(tǒng)一的管理。
無論try所指定的程序塊中是否會(huì)拋出例外,finally所指定的代碼都要被執(zhí)行
通常在finally語句中可以進(jìn)行資源的清除工作,如:關(guān)閉打開文件,刪除臨時(shí)文件
finally { try { in.close(); } catch (IOException e) { e.printStackTrace(); } }
6.聲明方法拋出的異常
一些方法處理不了一些Exception,可以拋出,給其他方法處理

public class Test { public static void main(String[] args) { try { new Test().f2(); } catch (IOException e) { e.printStackTrace(); } } void f() throws FileNotFoundException, IOException { FileInputStream in = new FileInputStream("myfile.txt"); int b; b = in.read(); while (b != -1) { System.out.print((char) b); b = in.read(); } } void f2() throws IOException { //處理f中的異常 f(); //運(yùn)行這種情況,調(diào)用f2時(shí),給f來處理 }}結(jié)果為:java.io.FileNotFoundException: myfile.txt(系統(tǒng)找不到指定的文件。) at java.io.FileInputStream.open(NativeMethod) at java.io.FileInputStream.(Unknown Source) at java.io.FileInputStream.(Unknown Source) at Test1.Test.f(Test.java:12) at Test1.Test.f2(Test.java:30) at Test1.Test.main(Test.java:6)
運(yùn)行是結(jié)果是:myfile.txt (系統(tǒng)找不到指定的文件。)
另一個(gè)例子:
public class Test { public static void main(String[] args) { Test test = new Test(); try { test.method1(); } catch (Exception e) { e.printStackTrace(); } } public void method1() throws Exception { method2(); } public void method2() throws Exception { method3(); } public void method3() throws Exception { throw new Exception("SomeException occur inmethod3"); }}結(jié)果是:java.lang.Exception: SomeException occur in method3 at Test1.Test.method3(Test.java:21) at Test1.Test.method2(Test.java:18) at Test1.Test.method1(Test.java:15) at Test1.Test.main(Test.java:8)7.一些其他問題
在try后面catch不能先大后小,不能先IoException,后FileNotFoundException,因FileNotFoundException包括在IoException中。
使用自定義的異常:
class 異常類名 extends Exception{ public異常類名(String msg) { super(msg); }}
1.通過繼承java.lang.Exception類聲明自己的異常類
2.在方法適當(dāng)?shù)奈恢蒙勺远x異常的實(shí)例,并用throw語句拋出
3.在方法的聲明部分用throws語句聲明該方法可能拋出的異常
public class MyException extends Exception { private int id; public MyException(String message, int id) { super(message); this.id = id; } public int getId() { return id; }}public class Test { public void regist(int num) throws MyException { if (num < 0) { throw new MyException("人數(shù)為負(fù)值,不合理", 3); } System.out.println("登記人數(shù)" + num); } public void manager() { try { regist(-1); } catch (MyException e) { System.out.println("登記失敗,出錯(cuò)類型碼=" + e.getId()); e.printStackTrace(); //輸出的第一行包含該對(duì)象的tostring()方法的結(jié)果。 } System.out.println("操作結(jié)束"); } public static void main(String[] args) { Test t = new Test(); t.manager(); }}結(jié)果為:登記失敗,出錯(cuò)類型碼=3Test1.MyException: 人數(shù)為負(fù)值,不合理 at Test1.Test.regist(Test.java:16) at Test1.Test.manager(Test.java:22) at Test1.Test.main(Test.java:31)操作結(jié)束
聲明并拋出異常
重寫方法需要拋出與原方法所拋出異常類型一致異常或不拋出異常
class A{
public void method() throws IOException{……}
//B1的繼承就不對(duì),必須要和原方法一致,既不能大,也不能小
class B1 exrends A{public void method() throwsFileNotFoundException{……}}
}
class B2 extends A{public void method(){……}}這是可以的
新聞熱點(diǎn)
疑難解答
圖片精選
網(wǎng)友關(guān)注