java-異常

異常簡(jiǎn)介

異常指阻止當(dāng)前方法繼續(xù)執(zhí)行的問(wèn)題,如:文件找不到、網(wǎng)絡(luò)連接失敗、非法參數(shù)等。發(fā)現(xiàn)異常的理想時(shí)期是編譯階段,然而編譯期間.不能找出所有的異常,余下的問(wèn)題須在運(yùn)行期間.
java中的異常分為可查異常不可查異常

  1. 可查異常
    即編譯時(shí)異常,指編譯器在編譯時(shí)可以發(fā)現(xiàn)的錯(cuò)誤,程序在運(yùn)行時(shí)很容易出現(xiàn)的異常狀況,這些異常可以預(yù)計(jì),所以在編譯階段就必須手動(dòng)進(jìn)行捕捉處理,即要么用try-catch語(yǔ)句捕獲它,要么用throws子句聲明拋出,否則編譯無(wú)法通過(guò)。如IOException、SQLException以及用戶自定義的Exception異常
  2. 不可查異常
    不可查異常包括運(yùn)行時(shí)異常(runtimeException)和錯(cuò)誤(error),他們都是在程序運(yùn)行時(shí)出現(xiàn)的。異常和錯(cuò)誤的區(qū)別:異常能被程序本身可以處理,錯(cuò)誤是無(wú)法處理
    運(yùn)行時(shí)異常(runtimeException)指的是程序在運(yùn)行時(shí)才會(huì)出現(xiàn)的錯(cuò)誤,由程序員自己分析代碼決定是否用try...catch進(jìn)行捕捉處理。如nullpointerException,classcastException,indexoutofboundsException。
    錯(cuò)誤(error),是程序無(wú)法處理的錯(cuò)誤,表示運(yùn)行應(yīng)用程序中較嚴(yán)重問(wèn)題,如系統(tǒng)崩潰,虛擬機(jī)錯(cuò)誤,動(dòng)態(tài)連接失敗等。大多數(shù)錯(cuò)誤與代碼編寫者執(zhí)行的操作無(wú)關(guān),而表示代碼運(yùn)行時(shí)JVM(Java虛擬機(jī))出現(xiàn)的問(wèn)題。例如,Java虛擬機(jī)運(yùn)行錯(cuò)誤(VirtualMachineError),當(dāng)JVM不再有繼續(xù)執(zhí)行操作所需的內(nèi)存資源時(shí),將出現(xiàn)OutOfMemoryError。這些異常發(fā)生時(shí),Java虛擬機(jī)(JVM)一般會(huì)選擇線程終止。這些錯(cuò)誤表示故障發(fā)生于虛擬機(jī)自身、或者發(fā)生在虛擬機(jī)試圖執(zhí)行應(yīng)用時(shí),如Java虛擬機(jī)運(yùn)行錯(cuò)誤(VirtualMachineError)、類定義錯(cuò)(NoClassDefFoundError)等。這些錯(cuò)誤是不可查的,即不需要捕獲和處理,因?yàn)樗鼈冊(cè)趹?yīng)用程序的控制和處理能力之外,而且絕大多數(shù)是程序運(yùn)行時(shí)不允許出現(xiàn)的狀況。對(duì)于設(shè)計(jì)合理的應(yīng)用程序來(lái)說(shuō),即使確實(shí)發(fā)生了錯(cuò)誤,本質(zhì)上也不應(yīng)該試圖去處理它所引起的異常狀況。
    Java異常類層次結(jié)構(gòu)圖:

從上圖可以看出Java通過(guò)API中Throwable類的眾多子類描述各種不同的異常。因而,Java異常都是對(duì)象,是Throwable子類的實(shí)例.
在Java中,所有的異常都有一個(gè)共同的祖先Throwable(可拋出)。Throwable指定代碼中可用異常傳播機(jī)制通過(guò)Java應(yīng)用程序傳輸?shù)娜魏螁?wèn)題的共性。

異常處理機(jī)制

當(dāng)異常發(fā)生時(shí),將使用new在堆上創(chuàng)建一個(gè)異常對(duì)象,對(duì)于這個(gè)異常對(duì)象,有兩種處理方式.
1.使用throw關(guān)鍵字將異常對(duì)象拋出,則當(dāng)前執(zhí)行路徑被終止,異常處理機(jī)制將在其他地方尋找catch塊對(duì)異常進(jìn)行處理.
2.使用try...catch在當(dāng)前邏輯中就進(jìn)行捕獲處理.

throws 和throw

  1. throws: 一個(gè)方法在聲明時(shí)可以使用throws關(guān)鍵字聲明可能會(huì)產(chǎn)生的若干異常。
  2. throw: 拋出異常,并退出當(dāng)前方法或作用域。

用throws聲明要拋出的異常,實(shí)際可以不拋出。而用throw拋出的異常也可以不聲明。不過(guò)Java鼓勵(lì)程序員把可能會(huì)拋出的異常提前聲明,這是一種優(yōu)雅的做法。

自定義異常

Java的異常體系不可能包括所有的異常情況,所以可以自己定義異常類來(lái)表示程序中可能會(huì)遇到的特定問(wèn)題。

public class MyException extends RuntimeException {
    public MyException() {
    }
public MyException(String message) {
        super(message);
    }
}

在 MyException 這個(gè)自定義異常中,定義了兩個(gè)構(gòu)造器。一個(gè)是默認(rèn)構(gòu)造器,一個(gè)接收一個(gè)字符串作為參數(shù)。在第二個(gè)構(gòu)造器中,可以看出調(diào)用了基類構(gòu)造器,所傳字符串可以通過(guò)getMessage()方法獲取。

public class ExceptionTest {
    public static void f(){
        System.out.println("Throwing Exception from f()");
        throw new MyException();
    }

    public static void g(){
        System.out.println("Throwing Exception from g()");
        throw new MyException("Originated in g()");
    }


    public static void main(String[] argv) throws Exception {
        try{
            f();
        }catch(MyException e){
            System.out.println(e.getMessage());
            e.printStackTrace(System.out);
        }
    }
}

在main函數(shù)中調(diào)用g(),運(yùn)行結(jié)果如下



可以總結(jié)出以下兩個(gè)函數(shù):

  1. getMessage():獲取一些描述性信息
  2. printStackTrace():從方法調(diào)用出到異常拋出處的方法調(diào)用序列

重新拋出異常

有時(shí)希望把捕獲的異常重新拋出,在catch中已經(jīng)得到了對(duì)當(dāng)前異常對(duì)象的引用,可以將其重新拋出。

public class ExceptionTest {

    public static void g() {
        throw new MyException("Originated in g()");
    }

    public static void h() {
        try {
            g();
        } catch (MyException e) {
            System.out.println("An Exception was thrown from g()");
            throw e;
        }
    }

    public static void k() throws Exception {
        try {
            g();
        } catch (MyException e) {
            System.out.println("An Exception was thrown from g()");
            throw (Exception) e.fillInStackTrace();
        }
    }


    public static void main(String[] argv) throws Exception {
        try {
            h();
        } catch (MyException e) {
            System.out.println(e.getMessage());
            e.printStackTrace(System.out);
        }
        System.out.println();

        try {
            k();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            e.printStackTrace(System.out);
        }
    }
}

從運(yùn)行結(jié)果可以看出,如果只是將異常拋出,那么printStackTrace()顯示的仍是原來(lái)拋出點(diǎn)的調(diào)用棧信息,并非重新拋出點(diǎn)的信息,若想更新信息,可以調(diào)用
fillInStackTrace()方法,它通過(guò)把當(dāng)前調(diào)用棧信息填入原來(lái)那個(gè)異常對(duì)象而建立。這樣調(diào)用fillInStackTrace()的那一行就會(huì)新的異常發(fā)生點(diǎn)。

使用finally清理

在java中finally的存在并不是為了釋放內(nèi)存資源,因?yàn)閖ava有垃圾回收機(jī)制,因此需要java釋放的資源主要是:已經(jīng)打開的文件或網(wǎng)絡(luò)連接等。
在try中無(wú)論有沒有捕獲異常,finally都會(huì)被執(zhí)行。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 通俗編程——白話JAVA異常機(jī)制 - 代碼之道,編程之法 - 博客頻道 - CSDN.NEThttp://blog...
    葡萄喃喃囈語(yǔ)閱讀 3,337評(píng)論 0 25
  • Java異常 異常指不期而至的各種狀況,如:文件找不到、網(wǎng)絡(luò)連接失敗、非法參數(shù)等。異常是一個(gè)事件,它發(fā)生在程序運(yùn)行...
    java部落閱讀 3,662評(píng)論 1 13
  • 概念介紹 異常是發(fā)生在程序執(zhí)行過(guò)程中阻礙程序正常執(zhí)行的錯(cuò)誤事件,當(dāng)一個(gè)程序出現(xiàn)錯(cuò)誤時(shí),可能的情況有如下3種: 語(yǔ)法...
    niaoge2016閱讀 5,653評(píng)論 2 20
  • 4.2 拋出異常 任何Java代碼都可以拋出異常,如:自己編寫的代碼、來(lái)自Java開發(fā)環(huán)境包中代碼,或者Java運(yùn)...
    java部落閱讀 882評(píng)論 0 1
  • 初識(shí)異常(Exception) 比如我們?cè)谌?shù)組里面的某個(gè)值得時(shí)候,經(jīng)常會(huì)出現(xiàn)定義的取值范圍超過(guò)了數(shù)組的大小,那么...
    iDaniel閱讀 1,982評(píng)論 1 2

友情鏈接更多精彩內(nèi)容