欧美一级特黄大片做受成人-亚洲成人一区二区电影-激情熟女一区二区三区-日韩专区欧美专区国产专区

Java中如何對異常進(jìn)行處理

這篇文章將為大家詳細(xì)講解有關(guān)Java中如何對異常進(jìn)行處理,文章內(nèi)容質(zhì)量較高,因此小編分享給大家做個參考,希望大家閱讀完這篇文章后對相關(guān)知識有一定的了解。

目前創(chuàng)新互聯(lián)公司已為成百上千的企業(yè)提供了網(wǎng)站建設(shè)、域名、網(wǎng)頁空間、網(wǎng)站托管、服務(wù)器租用、企業(yè)網(wǎng)站設(shè)計(jì)、滄源網(wǎng)站維護(hù)等服務(wù),公司將堅(jiān)持客戶導(dǎo)向、應(yīng)用為本的策略,正道將秉承"和諧、參與、激情"的文化,與客戶和合作伙伴齊心協(xié)力一起成長,共同發(fā)展。


異常及異常處理

Java中如何對異常進(jìn)行處理

什么是異常?總結(jié)為一句話就是:程序在執(zhí)行過程中產(chǎn)生的異常情況。當(dāng)某些事情出現(xiàn)了錯誤異常就會發(fā)生,比如打開一個并不存在的文件、嘗試在一個為null的對象上調(diào)用方法等等,都會發(fā)生異常。

異常是不可預(yù)知的,可是一旦它發(fā)生了就需要進(jìn)行異常處理,可謂知錯就改善莫大焉!異常處理是一種錯誤處理機(jī)制,如果你不對異常做任何處理,異常將會導(dǎo)致應(yīng)用程序崩潰。

Java中如何對異常進(jìn)行處理

一旦你選擇了進(jìn)行處理異常,也就意味著你承認(rèn)問題的發(fā)生,采用必要要的措施去讓應(yīng)用程序從錯誤中恢復(fù),從而讓業(yè)務(wù)繼續(xù)進(jìn)行,阻止應(yīng)用程序崩潰。

Java中如何對異常進(jìn)行處理

實(shí)際上異常處理并不是處理問題的唯一一種方式,如今的高級語言一般都有異常處理機(jī)制,但比較古老的如C語言是通過返回錯誤碼的方式來處理異常的。比如數(shù)組越界比較常用的返回值是-1。

這種方式的優(yōu)點(diǎn)是代碼邏輯易于推理,沒有中斷和代碼跳轉(zhuǎn)。另一方面,這種處理方式鼓勵函數(shù)的調(diào)用者總是檢查返回的錯誤碼。但是這種檢查容易造成代碼污染,導(dǎo)致代碼的可讀性和可維護(hù)性降低。

錯誤代碼的另一個嚴(yán)重的缺點(diǎn)是缺乏上下文信息,你可能知道錯誤碼“-5”代表找不到文件,但究竟找不到哪個文件呢!錯誤碼就無法表述了。

Java中如何對異常進(jìn)行處理

錯誤代碼一般用于面向過程的語言,對面向?qū)ο蟮母呒壵Z言,有些場景是無能為力的,比如構(gòu)造函數(shù)異常,是無法返回錯誤碼的。

異常處理

Java中如何對異常進(jìn)行處理

當(dāng)異常被拋出時,應(yīng)用程序的流程就會被中斷,如果沒能及時處理異常,應(yīng)用程序?qū)⒈罎ⅰS脩魧⒖吹疆惓P畔?,但那些信息大多他們是看不懂的,這將是一個很糟糕的用戶體驗(yàn),實(shí)際上異常信息還可以包裝成非常友好的提示。

所以必須進(jìn)行異常處理,哪怕是為了提高用戶體驗(yàn)、記錄問題日志、優(yōu)雅地退出應(yīng)用程序等。

我們可以使用代碼塊(try...catch...)來進(jìn)行異常處理,當(dāng)發(fā)生異常,通過try執(zhí)行代碼,如果發(fā)生異常,應(yīng)用程序的流程將轉(zhuǎn)移到catch中,catch捕捉到異常并進(jìn)行必要的處理。

以上表述的異常處理原理對初學(xué)者依然比較抽象,我們來舉個例子

package com.zqf;

public class App
{
    public static void main(String[] args){
        System.out.println("First line");
        System.out.println("Second line");
        System.out.println("Third line");
        //初始化具有3個元素的素組
        int[] myIntArray = new int[]{1, 2, 3};
        print4thItemInArray(myIntArray);
        System.out.println("Fourth line");
        System.out.println("Fith line");
    }

    private static void print4thItemInArray(int[] arr) {
        //獲取第4個(下標(biāo)3)元素,因?yàn)闆]有所以拋出異常
        System.out.println(arr[3]);
        System.out.println("Fourth element successfully displayed!");
    }
}

分析下這個程序,在main中初始化有3個元素的數(shù)組,把這個數(shù)組傳遞給私有方法print4thItemInArray,在print4thItemInArray中試圖獲取數(shù)組的第4個元素,由于沒有第4個元素將拋出“ArrayIndexOutOfBoundsException”異常,應(yīng)用程序只會打印到“Third line”。

執(zhí)行應(yīng)用輸出結(jié)果如下

First line 

Second line 

Third line 

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 3

   at com.zqf.App.print4thItemInArray(App.java:20) 

   at com.zqf.App.main(App.java:14) 

Process finished with exit code 1

現(xiàn)在我們修改下,增加異常處理

package com.zqf;

public class App {
    public static void main(String[] args) {
        System.out.println("First line");
        System.out.println("Second line");
        System.out.println("Third line");
        //初始化具有3個元素的素組
        int[] myIntArray = new int[]{1, 2, 3};

        try {//捕捉異常
            print4thItemInArray(myIntArray);
        }catch (ArrayIndexOutOfBoundsException ex){//異常處理
            System.out.println("Have no four items!");
        }
        System.out.println("Fourth line");
        System.out.println("Fith line");
    }

    private static void print4thItemInArray(int[] arr) {
        //獲取第4個(下標(biāo)3)元素,因?yàn)闆]有所以拋出異常
        System.out.println(arr[3]);
        System.out.println("Fourth element successfully displayed!");
    }
}

現(xiàn)在運(yùn)行看看輸出

First line 

Second line 

Third line                

Have no four items! 

Fourth line 

Fith line

實(shí)際上這次的異常依然會發(fā)生,因?yàn)榈?個元素的確不存在,所以在"Fourth element successfully displayed!"輸出之前就拋出了異常,中斷執(zhí)行流程,但流程跳轉(zhuǎn)到catch語句塊了,catch只打印了一條“Have no four items”,繼續(xù)向下執(zhí)行。

Java異常體系

Java中如何對異常進(jìn)行處理

在Java中,所有的異常都有一個共同的祖先Throwable,它有2個子類:Exception(異常)和Error(錯誤),它們又各自有大量的子類。Exception(異常)和Error(錯誤)的共性和區(qū)別:兩者都可以被捕捉,但前者可以被應(yīng)用程序本身處理,后者是嚴(yán)重的,是無法恢復(fù)處理的。

Java中如何對異常進(jìn)行處理

最佳實(shí)踐

Java中如何對異常進(jìn)行處理

1
     
用Finally或Try-With-Resource清理資源
   

我們經(jīng)常在try語句塊使用資源,比如InputStream,使用完后需要關(guān)閉。經(jīng)常犯的錯誤是在try語句塊中關(guān)閉資源。如

public void doNotCloseResourceInTry() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);

        // 使用inputStream讀取文件

        // 不要這樣做
        inputStream.close();
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

這種方式看似非常完美,不會有異常拋出,所有的語句在try中執(zhí)行,關(guān)閉IputStream釋放資源。但試想一下:如果在“inputStream.close()”語句之前就拋出異常,會怎樣呢?正常的流程會被中斷并跳轉(zhuǎn),導(dǎo)致InputStream根本沒關(guān)閉。

因此,應(yīng)該把清理資源的代碼放在finally或try-with-resource語句中。不管是正常執(zhí)行完try語句塊,還是異常處理完畢,都會執(zhí)行finally語句塊,而你需要確保在finally關(guān)閉所有打開的資源。

public void doNotCloseResourceInTry() {
    FileInputStream inputStream = null;
    try {
        File file = new File("./tmp.txt");
        inputStream = new FileInputStream(file);

        // 使用inputStream讀取文件
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    } finally {
        if (inputStream != null) {
            try {
                inputStream.close();
            } catch (Exception e) {
                log.error(e);
            }
        }
    }
}

在JDK7引入了try-with-resource的語法,簡單來說當(dāng)一個資源對象(如InputSteam對象)實(shí)現(xiàn)了AutoCloseable接口,那么就可以在try關(guān)鍵字后的括號里創(chuàng)建實(shí)例,當(dāng)try-catch語句塊執(zhí)行完畢后,會自動關(guān)閉資源,代碼也會簡潔許多。如下

public void doNotCloseResourceInTry() {
    File file = new File("./tmp.txt");
    try (FileInputStream inputStream = new FileInputStream(file)) {

        // 使用inputStream讀取文件
    } catch (FileNotFoundException e) {
        log.error(e);
    } catch (IOException e) {
        log.error(e);
    }
}

2
     

     
拋出具體異常 

你拋出的異常越具體越好,不熟悉你代碼的同事或者幾個月之后的你,可能需要調(diào)用你這些方法并進(jìn)行異常處理,所以盡可能多的提供信息,讓你的API更容易理解,比如能用NumberFormatException就不要用 IllegalArgumentException,絕對避免直接使用不具體的Exception類。

//不建議
public void doNotDoThis() throws Exception { ... }
//建議
public void doThis() throws NumberFormatException { ... }
3
做好注釋/文檔 

只要你在方法聲明異常,就需要做好Javadoc的注釋。這點(diǎn)和上一條最佳實(shí)踐有相同的目標(biāo):提供給調(diào)用者盡可能多的信息,便于避免異常或進(jìn)行異常處理。所以請確保你在Javadoc中添加了"@throws"聲明,并且描述了造成異常的情況。

/**
* This method does something extremely useful ...
*
* @param input
* @throws MyBusinessException if ... happens
*/
public void doSomething(String input) throws MyBusinessException { ... }

4
 異常攜帶可描述的信息 

這條最佳實(shí)踐和前面兩條有點(diǎn)相似,但這條提供的信息不單是給方法調(diào)用者看的,而更多的是為了給記錄日志或監(jiān)控工具提供的,便于排查異常。實(shí)際上一般的異常類名就已經(jīng)描述了問題的類型,你不必提供大量的附加信息,簡潔凝練即可。比如NumberFormatException,當(dāng)java.lang.Long構(gòu)造函數(shù)拋出異常時會提供一句簡短且清晰的文本來描述。

try {
 new Long("xyz");
} catch (NumberFormatException e) {
 log.error(e);
}

NumberFormatException 的名字就已經(jīng)告訴你異常的種類,它攜帶的信息僅告訴你提供的字符串會導(dǎo)致異常,但如果異常名字不能表達(dá)異常種類,就需要提供更多的信息。上述的異常信息如下

17:17:26,386 ERROR TestExceptionHandling:52 - java.lang.NumberFormatException: For input string: "xyz"

如果你仔細(xì)看下JDK的源碼,就會清楚java.lang.Long在構(gòu)造器中做了各種校驗(yàn),當(dāng)某些校驗(yàn)失敗會調(diào)用NumberFormatException.forInputString,而靜態(tài)方法forInputString會把java.lang.Long的構(gòu)造參數(shù)格式化后再構(gòu)造一個新的NumberFormatException實(shí)例并拋出

/**
 * Factory method for making a <code>NumberFormatException</code>
 * given the specified input which caused the error.
 *
 * @param   s   the input causing the error
 */
static NumberFormatException forInputString(String s) {
    return new NumberFormatException("For input string: \"" + s + "\"");
}
5
 線捕捉子類異常 

很多IDE都會幫助你進(jìn)行最佳實(shí)踐,如果你先捕捉父類異常再捕捉子類異常,它們會告訴你后面的代碼不可到達(dá)或者警告已經(jīng)被捕捉,因?yàn)槭前凑誧atch在在代碼中順序執(zhí)行的。

所以如果先捕捉IllegalArgumentException,將不能捕捉到其子類NumberFormatException,因此最佳時間是總是先捕捉更多信息的異常(子類),再捕捉父類。如

public void catchMostSpecificExceptionFirst() {
    try {
        doSomething("A message");
    } catch (NumberFormatException e) {
        log.error(e);
    } catch (IllegalArgumentException e) {
        log.error(e)
    }
}

6
 不要捕捉Throwable 

從Java異常體系的圖中可知,Throwable是所有異常(Exception)和錯誤(Error)的祖先,Throwable是可以被捕捉,但請不要捕捉。如果你捕捉了Throwable,那么不僅僅是捕捉了異常,還捕捉了錯誤。但錯誤是無法恢復(fù),它是被JVM拋出的嚴(yán)重錯誤,應(yīng)用程序?qū)@類錯誤是無能為力的。

//不要捕捉Throwable
public void doNotCatchThrowable() {
    try {
        // do something
    } catch (Throwable t) {
        // don't do this!
    }
}

7
 不要忽略異常 

你是否記得曾幾何時,在分析bug時遇到代碼只執(zhí)行了前半部分,但卻不知為何。有些開發(fā)者經(jīng)常捕捉了異常,但憑經(jīng)驗(yàn)認(rèn)為異常決定不可能發(fā)生,導(dǎo)致沒有做異常處理。

public void doNotIgnoreExceptions() {
    try {
        // do something
    } catch (NumberFormatException e) {
        // this will never happen,I'm sure!!
    }
}

實(shí)際上在大多數(shù)情況下它都發(fā)生了,因?yàn)殡S著時間和業(yè)務(wù)邏輯的變更,try代碼塊的內(nèi)容變更了,導(dǎo)致了異常發(fā)生,而你的自信不僅害了你也害了后來人。建議catch中至少要留一條日志,來告知異常問題,方便排查。

public void logAnException() {
    try {
        // do something
    } catch (NumberFormatException e) {
        log.error("This should never happen: " 
         + e + ",but I get a mistake!");
    }
}

8
 不要在僅僅記錄日志后向上拋出異常 

“不要在僅僅記錄日志后向上拋出異?!?,這是最佳實(shí)踐中最容易被忽視的一條。你會發(fā)現(xiàn)在大量的代碼片段,甚至類庫中經(jīng)常捕捉異常、記錄日志,然后拋出異常。

try {
 new Long("xyz");
} catch (NumberFormatException e) {
 log.error(e);
 throw e;
}

直觀的感覺是記錄異常,然后拋出異常讓調(diào)用者可以恰當(dāng)?shù)奶幚?,但同一個異常多處日志記錄,會讓人迷惑,請參考第4條最佳實(shí)踐:簡潔凝練。

17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException: For input string: "xyz"
Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"
 at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
 at java.lang.Long.parseLong(Long.java:589)
 at java.lang.Long.(Long.java:965)
 at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)
 at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)

如果你真的需要給調(diào)用者提供更多信息,可以參考下一條最佳實(shí)踐:包裝異常。


9
 不消費(fèi)包裝異常 

比較可取的做法是捕捉到標(biāo)準(zhǔn)異常,根據(jù)實(shí)際業(yè)務(wù)自定義包裝異常再向上拋出。在包裝異常時通常把原始異常作為構(gòu)造參數(shù)傳進(jìn)來,否則會丟失棧的跟蹤信息,造成分析困難。

public void wrapException(String input) throws MyBusinessException {
 try {
  // do something
 } catch (NumberFormatException e) {
  throw new MyBusinessException("A message that describes the error.", e);
 }
}

關(guān)于Java中如何對異常進(jìn)行處理就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,可以學(xué)到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

網(wǎng)站題目:Java中如何對異常進(jìn)行處理
網(wǎng)頁網(wǎng)址:http://aaarwkj.com/article2/pdheoc.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、ChatGPT、網(wǎng)站策劃靜態(tài)網(wǎng)站、服務(wù)器托管

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

營銷型網(wǎng)站建設(shè)
亚洲综合国产一二三四五区| 另类视频网站在线观看| 蜜桃成人一区二区三区| 91免费在线观看国产精品| 国产av剧情精品麻豆| 2020亚洲欧美日韩在线| 亚洲成人日韩在线播放 | 偷拍福利视频一区二区三区| 一本色道久久88综合日韩| 国产在线视频不卡一区| 91精品啪在线观看国产日本| 首页亚洲一区二区三区| 丰满少妇一级淫片在线播放| 韩国福利短片在线观看| 日韩黄色大片免费在线观看| 国产一级内射麻豆91| 超碰97免费在线观看| 熟妇一区二区三区av| 午夜福利影片免费观看| 日本姜女黄视频免费看| 天堂av在线观看播放| 日韩高清av不卡一区二区三区 | 国产丰满熟女视频免费| 强d乱码中文字幕在线| 黄色三级欧美一区二区| 日本免费熟女一区二区| 99久久久国产精品日本久久区一| 日韩欧美一区二区三区| 久久好大好爽要死了欧美| 亚洲精品久久麻豆蜜桃| 国产一区二区三区日本精品| 日韩综合欧美激情另类| 亚洲中文有码一区二区| 亚洲精品乱码在线播放| 成人av影视中文字幕| 日韩不卡高清免费在线视频| 欧美日韩一区二区三区四区高清 | 日本精彩视频一区二区| 亚洲亚洲精品av在线动| 天堂av在线资源观看| 传媒视频免费在线观看|