異常

一、異常的分類

異常具有自己的語(yǔ)法和特定的繼承結(jié)構(gòu)。異常對(duì)象都是繼承Throwable類的一個(gè)實(shí)例。如果java中內(nèi)置的異常類不能滿足需求,用戶也可以創(chuàng)建自己的異常類。


Java中的異常層次結(jié)構(gòu).png

java語(yǔ)言規(guī)范:繼承Error類或RuntimeException的所有異常成為非受查異常,所有其他的異常(IOException)稱為受查異常。編譯器將檢查是否為所有的受查異常提供了異常處理器。

二、每類異常描述的錯(cuò)誤

其中,每類層次結(jié)構(gòu)描述的錯(cuò)誤如下:


錯(cuò)誤描述.png

從圖中可以看出:“如果出現(xiàn)RuntimeException異常,一定是程序的問題”。應(yīng)該通過檢查數(shù)組的下標(biāo)是否越界來避免ArryIndexOutOfBoundsException異常;在使用變量時(shí)檢查是否為null來杜絕NullPointerException異常的發(fā)生。

三、聲明異常

一個(gè)方法不僅需要告訴編譯器將要返回什么值,還要告訴編譯器有可能發(fā)生聲明錯(cuò)誤。方法應(yīng)該在首部聲明所有可能拋出的異常,這樣可以從首部反映出這個(gè)方法可能拋出哪類受查異常。在編寫方法時(shí),不必將所有可能拋出的異常都進(jìn)行聲明。

1、需拋出異常的4種情況:

(1)調(diào)用一個(gè)拋出受查異常的方法
(2)程序運(yùn)行過程中發(fā)現(xiàn)錯(cuò)誤,并且利用throw語(yǔ)句拋出一個(gè)受查異常
(3)程序出現(xiàn)錯(cuò)誤,如,a[-1]會(huì)拋出一個(gè)ArryIndexOutOfBoundsException這樣的非受查異常
(4)java虛擬機(jī)和運(yùn)行時(shí)庫(kù)出現(xiàn)的內(nèi)部錯(cuò)誤

2、聲明受查異常

(1)如果出現(xiàn)上述前2種情況,必須要告訴調(diào)用這個(gè)方法的程序員有可能拋出異常。對(duì)于那些可能被他人使用的方法,應(yīng)該根據(jù)異常規(guī)范,在方法的首部聲明這個(gè)方法可能拋出的異常。

class MyAnimation
{
    ......
    public Image loadImage(String s) throws IOException
    {
       ......
    }
}

(2)如果一個(gè)方法有可能拋出多個(gè)受查異常類型,必須在方法的首部列出所有的異常類。每個(gè)異常類之間用逗號(hào)隔開。

class MyAnimation
{
    ......
    public Image loadImage(String s) throws FileNotFoundException,EOFException
    {
       ......
    }
}
3、非受查異常不需要聲明

不需要聲明java的內(nèi)部錯(cuò)誤,即從Error繼承的錯(cuò)誤(非受查異常)。任何程序代碼都具有拋出那些異常的潛能,而我們對(duì)其沒有任何控制能力。同樣,也不應(yīng)該聲明從RuntimeException繼承的那些非受查異常。因?yàn)檫@些運(yùn)行時(shí)錯(cuò)誤完全在我們的控制之下。如果特別關(guān)注這些引發(fā)的錯(cuò)誤,就應(yīng)該將更多的時(shí)間花費(fèi)在修正程序設(shè)計(jì)上,而不是說明這些錯(cuò)誤發(fā)生的可能性上。
總之,一個(gè)方法必須聲明所有可能拋出的受查異常,而非受查異常要么不可控制(Error),要不就應(yīng)該避免發(fā)生(RuntimeException)。如果方法沒有聲明所有可能發(fā)生的受查異常,編譯器就會(huì)發(fā)出一個(gè)錯(cuò)誤消息。

4、需要注意的是:

(1)如果類中的一個(gè)方法聲明將會(huì)拋出一個(gè)異常時(shí),而這個(gè)異常是某個(gè)特定類的實(shí)例時(shí),則這個(gè)方法就有可能拋出一個(gè)這個(gè)類的異常,或者是這個(gè)類的任意一個(gè)子類的異常。例:FileInputStream構(gòu)造器聲明將有可能拋出一個(gè)IOException異常,然而并不知道具體是哪種IOException異常。它既可以是IOException異常,也可以是其子類的異常,如FileNotFoundIOException。
(2)如果在子類中覆蓋了超類的一個(gè)方法,子類方法中聲明的受查異常不能比超類方法中聲明的異常更通用(也就是說,子類方法中可以拋出更特定的異常,或根本不拋出任何異常)。特別要說明的是,如果超類方法沒有拋出任何受查異常,子類也不能拋出任何受查異常。那么子類的受查異常要怎么處理呢?這就涉及到捕獲異常了(見下節(jié))。

四、如何拋出異常

(1)找到一個(gè)合適的異常類:如EOFException異常類,繼承IOException
(2)創(chuàng)建這個(gè)類的一個(gè)對(duì)象:
throw new EOFException;或
EOFException e=new EOFException();
throw e;
(3)將對(duì)象拋出

String readData(Scanner in) throws  EOFException
{
    ......
    while (......)
    {
        if (!in.hashnext())
            {
                if (n<len)
                    throw new  EOFException();
            }
            ......
    }
    return s;
}

一旦方法拋出了異常,這個(gè)方法就不可能返回到調(diào)用者。也就是說,不必為返回的默認(rèn)值或錯(cuò)誤代碼擔(dān)憂。需要注意的是,在java中,只能拋出Throwable子類的對(duì)象。

五、創(chuàng)建異常類

在程序中,可能會(huì)遇到任何標(biāo)準(zhǔn)異常類都不能充分地描述清楚地問題,在這種情況下可以創(chuàng)建自己地異常類。需要做的只是定義一個(gè)繼承Exception的類,或者繼承Exception子類的類,但是創(chuàng)建的異常類實(shí)質(zhì)上都被認(rèn)為是受查異常。習(xí)慣上,定義的類應(yīng)該包括兩個(gè)構(gòu)造器,一個(gè)是默認(rèn)的構(gòu)造器,另一個(gè)是帶有詳細(xì)信息的構(gòu)造器。

class FileFormatException extends IOException
{
    public FileFormatException() {}
    public FileFormatException(String gripe)
    {
        super(gripe);
    }
}

class FileFormatException extends Exception
{
    public FileFormatException() {}
    public FileFormatException(String gripe)
    {
        super(gripe);
    }
}

用法:聲明創(chuàng)建的異常并拋出:

public void getConfig() throws FileFormatException
{
    code
    throw new test();
}

如果不聲明,編譯器報(bào)錯(cuò)提示聲明,可見其為受查異常:

public void getConfig()
{
    code
    throw new test();
}

需要注意的是:標(biāo)準(zhǔn)異常與創(chuàng)建的異常不能混為一談,雖然FileFormatException繼承Exception,但方法的首部也必須要聲明IOException:
下列程序會(huì)報(bào)錯(cuò)Unhandled exception type FileNotFoundException:

public void getConfig() throws FileFormatException
{
    File filePath = new File(System.getProperty("user.home") + File.separator + "AppiumExecutor" + File.separator + "config1.properties");
    InputStream inputStream = new FileInputStream(filePath);
    String aa =  inputStream.toString();
    throw new FileFormatException("我是一個(gè)異常");
}

需要這樣寫:

public void getConfig() throws FileFormatException,IOException(或FileNotFoundException)
{
    File filePath = new File(System.getProperty("user.home") + File.separator + "AppiumExecutor" + File.separator + "config1.properties");
    InputStream inputStream = new FileInputStream(filePath);
    String aa =  inputStream.toString();
    throw new FileFormatException("我是一個(gè)異常");
}
最后編輯于
?著作權(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ù)。

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