日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > java >内容正文

java

Java异常处理终结篇——如何进行Java异常处理设计

發(fā)布時間:2025/1/21 java 97 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java异常处理终结篇——如何进行Java异常处理设计 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

【本文轉(zhuǎn)自于Java異常處理終結(jié)篇——如何進行Java異常處理設(shè)計】

有一句這樣話:一個衡量Java設(shè)計師水平和開發(fā)團隊紀(jì)律性的好方法就是讀讀他們應(yīng)用程序里的異常處理代碼。

本文主要討論開發(fā)Java程序時,如何設(shè)計異常處理的代碼,如何時拋異常,捕獲到了怎么處理,而不是講異常處理的機制和原理。

在我自己研究Java異常處理之前,我查過很多資料,翻過很多書藉,試過很多搜索引擎,換過很多英文和中文關(guān)鍵字,但是關(guān)于異常處理設(shè)計的文章實在太少,在我研究完Java異常處理之后,我面試過很多人,也問過很多老員工,極少碰到對Java異常有研究的人,看來研究這個主題的人很少,本文內(nèi)容本是個人研究異常時做的筆記,現(xiàn)整理一下與大家一起分享。

首先我們簡單的回顧一下基礎(chǔ)知識,Java中有兩種異常,嚴(yán)格的說是三種,包含四個類,層次圖如下:


Throwable是一個可拋類,只有其子類可以被關(guān)鍵字throw拋出,請勿直接繼承本類,Error是表示系統(tǒng)級錯誤,如內(nèi)存耗盡了,我們一般情況下不用管,Exception是所有異常的父類,所以他的子類,除了RuntimeException及其子類,是屬于編譯時異常,這種異常必須在代碼里被顯示的捕獲語句包住,否則編譯不過,而RuntimeException及其子類表示運行時異常,不強制要求寫出顯示的捕獲代碼,但如果沒有被捕獲到,則線程會被強制中斷。

我們主要關(guān)注后兩種,他們的特點已領(lǐng)教了,下面我們通過回答問題的方式來分析異常設(shè)計,在開始之前,請確保你已經(jīng)知道使這兩種異常:


捕獲到了編譯時異常怎么處理

這個話題恐怖是最古老的啦,網(wǎng)上的文章多數(shù)都是討論這個話題,但這些文章大部分只是給了幾條禁止的原則,他們是:1)不要直接忽略異常;2)不要用try-catch包住過多語句;3)不要用異常處理來處理程序的正??刂屏?#xff1b;4)不要隨便將異常迎函數(shù)棧向上傳遞,能處理盡量處理。他們都對,但是要做異常處理的設(shè)計,信息還是不夠,比如第一條他只是告訴了不要忽略,但沒有告訴我們怎么處理,所以很多人直接e.printStackTrace()了,這種處理比直接忽略是好一點,但還不夠好。對于第二條,他的理由是避免耗資源很大,不過“過多語句”這句話描述的太模糊了,沒說明到底多少才算過多,以致于很多人的try-catch語句只包住會拋編譯時異常的那一行代碼,如果一段代碼中有多行代碼會拋編譯時異常,那這一段代碼中可能有多個try-catch語句塊,像這樣:

[java]?view plaincopy print?
  • LLJTran?llj?=?new?LLJTran(file);??
  • try?{??
  • ????llj.read(LLJTran.READ_INFO,true);??
  • }?catch?(LLJTranException?e)?{??
  • ????//?...??
  • }??
  • ??
  • //?...??
  • ??
  • OutputStream?out?=?null;??
  • try?{??
  • ????File?out?=?new?File(file.getPath()+"_bak.jpg");??
  • ????llj.xferInfo(null,?out,?LLJTran.REPLACE,?LLJTran.REPLACE);??
  • }?catch?(IOException?e)?{??
  • ????//?...??
  • }??
  • ??
  • //?...??
  • ??
  • try?{??
  • ????out.close();??
  • }?catch?(IOException?e)?{??
  • ????//?...??
  • }??
  • 這樣有什么壞處呢,到處都是異常處理的代碼,很容易給人造成困惑,很難找出哪些是正常流程的代碼,而且還違背了Java異常機制的初衷,Java異常機制是為了把異常處理的代碼與正常流程的代碼分開,避免程序中出現(xiàn)過多的像傳統(tǒng)程序那樣的非法值判斷語句,以致于擾亂了正常流程。但上述代段充斥著try-catch語句塊,已經(jīng)擾亂了主流程,并極大影響了可讀性。

    try-catch既不能包太多代碼,又不能包太少,那應(yīng)該包多少才適合呢,這個問題我查過的資料中都沒有提,我的個人建議是包住邏輯關(guān)系緊密的代碼,比如打開文件,讀取文件,關(guān)閉文件,我認(rèn)為就是邏輯關(guān)系緊密的代碼,如果你發(fā)現(xiàn)包住的代碼很多,可以封裝一些方法,如讀取文件的代碼很長就應(yīng)該封裝成一個方法,這個方法可以申明IOException,(其實讀文件的細節(jié)本來屬于低層邏輯,打開,讀取,關(guān)閉才屬于同層邏輯,如果讀取代碼很短,初期為了省事才不封成讀取細節(jié)的代碼,不過后期可以重構(gòu)并封裝成方法,這是《重構(gòu)·改善繼有的代碼設(shè)計》一書中的思想——軟件應(yīng)該不斷的重構(gòu)和加善)。這樣才能達到把異常代碼與正常流程代碼分離的目的。

    第3)條沒問題,第4)條也有問題,“不要隨便”很模糊,那什么時候才能向上傳遞呢。

    吐槽完了,我們現(xiàn)在來說說到底該如何處理捕獲到的編譯時異常

    一、恢復(fù)并繼續(xù)執(zhí)行:這個結(jié)果是最完美的,也是編譯時異常出生的目的——捕獲異常,并恢復(fù)繼續(xù)執(zhí)行程序。所以如果你捕獲了一個異常是先盡力恢復(fù),這種情況其實就是在主方案行不通時,用備選方案,而且主方案能否行通不能事先知道,必須執(zhí)行的時候才能知道,所以在一般情況下,備選方案比主方案要的運行結(jié)果要差。比如一個視頻程序,它要調(diào)用一個下載節(jié)目列表的方法,可能如下:

    [java]?view plaincopy print?
  • InputStream?download()?throws?IOException?{??
  • ????//?...??
  • }??
  • 但服務(wù)器不保證總是可用,有可能被攻擊了,有可能其它原因,因為是個意外事件,所以又不可能事先知道,于是異常就發(fā)生在執(zhí)行過程中,幸好客戶端有備選方案,它在本地保存了一個默認(rèn)列表,當(dāng)服務(wù)器不可用時,就加載本地列表,所以客戶端對這個異常的處理可以如下: [java]?view plaincopy print?
  • public?void?loadProgramList()?{??
  • ????InputStream?inputStream;??
  • ????try?{??
  • ????????inputStream?=?download();??
  • ????}?catch?(IOException?e)?{??
  • ????????//?Log?this?exception??
  • ????????System.out.println("The?server?occurred?errors");??
  • ????????//?Use?the?local?file??
  • ????????inputStream?=?openLocalFile();??
  • ????}??
  • ??????
  • ????//...??
  • }??
  • ??
  • private?InputStream?download()?throws?IOException?{??
  • ????//?...??
  • }??
  • ??
  • private?InputStream?openLocalFile()?{??
  • ????//?...??
  • }??
  • 可惜的是,不是任何時候的異常都可以恢復(fù),反而一般情況是不能恢復(fù)的。

    二、向上傳播異常:向上傳播就是在本方法上用throws申明,本方法里的代碼不對某異常做任何處理。如果不能用上述恢復(fù)措施,就檢查能不能向上傳播,什么情況下可以向上傳播呢?有多種說法,一種說法是當(dāng)本方法恢復(fù)不了時,這個說法顯然是錯誤,因為上層也不一定能恢復(fù)。另外還有兩種說法是:1.當(dāng)上層邏輯可以恢復(fù)程序時;2.當(dāng)本方法除了打印之外不能做任何處理,而且不確定上層能否處理。這種兩種說法都是正確的,但還不夠,因為也有的情況,明確知道上層恢復(fù)不了也需要上層處理,所以我認(rèn)為正確的做法是:當(dāng)你認(rèn)為本異常應(yīng)該由上層處理時,才向上傳播。不過這得根據(jù)你程序的設(shè)計來靈活思考,比如你的類設(shè)計了一個上層方法集中處理異常,而下層有一些private方法只是簡單的用throws申明。當(dāng)上層方法捕獲到異常時,雖然不能恢復(fù)執(zhí)行,但可以做一些處理,如轉(zhuǎn)換成便于閱讀的文本,或者用下面討論的轉(zhuǎn)譯。

    三、轉(zhuǎn)譯異常:轉(zhuǎn)譯即把低層邏輯的異常轉(zhuǎn)化成為高層邏輯的異常,因為有可能低層邏輯的異常在高層邏輯中不能被理解,主要實現(xiàn)是新寫一個Exception的子類,然后在低層邏輯捕獲異常,改拋這個新寫的異常,比如剛剛那個視頻程序,他的主流程可能是:1.加載節(jié)目列表,2.顯示播放節(jié)目。而加載節(jié)目列表子流程又包含讀取節(jié)目文件、解析節(jié)目文件、顯示節(jié)目列表。而讀取節(jié)目文件有可能出現(xiàn)IO異常(有可能本地和網(wǎng)上的文件都讀不了了),解析節(jié)目文件可能出現(xiàn)解析異常,這時如果把這些異常,直接向上傳播,變成這樣,你覺得合理嗎:

    [java]?view plaincopy print?
  • public?void?mainFlow()?{??
  • ????//?1.load?program?list??
  • ????try?{??
  • ????????loadProgramList();??
  • ????}?catch?(IOException?e)?{??
  • ????????//?I?don't?understand?what?is?this?exception.??
  • ????}?catch?(ParseException?e)?{??
  • ????????//?I?don't?understand?what?is?this?exception.??
  • ????}??
  • ??????
  • ????//?2.play?program??
  • ????//?...??
  • }??
  • ??
  • public?void?loadProgramList()?throws?IOException,?ParseException?{??
  • ????//?1.Read?program?file??
  • ????InputStream?inputStream;??
  • ????try?{??
  • ????????inputStream?=?download();??
  • ????}?catch?(IOException?e)?{??
  • ????????//?Log?this?exception??
  • ????????System.out.println("The?server?occurred?errors");??
  • ????????//?Use?the?local?file??
  • ????????inputStream?=?openLocalFile();????//Maybe?throw?IOException.??
  • ????}??
  • ??????
  • ????//?2.Parse?program?file??
  • ????parserProgramFile(inputStream);????????//Maybe?throw?ParseException.??
  • ??????
  • ????//?3.Display?program?file??
  • ????//...??
  • }??
  • 由于loadProgramList將兩個可能的異常向上傳播,在mainFlow里,必須顯示捕獲這兩個異常,但在mainFlow根本就不能理解這兩個異常代表什么,mainFlow里只需要知道加載節(jié)目列表異常就可以了,所以我們可以寫一個異常類LoadProgramException代表加載節(jié)目異常,并在loadProgramList里拋出,于是代碼變成這樣: [java]?view plaincopy print?
  • public?void?mainFlow()?{??
  • ????//?1.load?program?list??
  • ????try?{??
  • ????????loadProgramList();??
  • ????}?catch?(LoadProgramException?e)?{????????//?look?at?here??
  • ????????//?...??
  • ????}??
  • ??????
  • ????//?2.play?program??
  • ????//?...??
  • }??
  • ??
  • public?void?loadProgramList()?throws?LoadProgramException?{????????//?look?at?here??
  • ????//?1.Read?program?file??
  • ????InputStream?inputStream?=?null;??
  • ????try?{??
  • ????????inputStream?=?download();??
  • ????}?catch?(IOException?e)?{??
  • ????????//?Log?this?exception??
  • ????????System.out.println("The?server?occurred?errors");??
  • ????????//?Use?the?local?file??
  • ????????try?{??
  • ????????????inputStream?=?openLocalFile();??
  • ????????}?catch?(IOException?e1)?{??
  • ????????????throw?new?LoadProgramException("Read?program?file?error.",?e1);????????//?look?at?here??
  • ????????}??
  • ????}??
  • ??????
  • ????//?2.Parse?program?file??
  • ????try?{??
  • ????????parserProgramFile(inputStream);??
  • ????}?catch?(ParseException?e)?{??
  • ????????throw?new?LoadProgramException("Parse?program?file?error.",?e);????????????//?look?at?here??
  • ????}??
  • ??????
  • ????//?3.Display?program?file??
  • ????//...??
  • }??
  • ??
  • //?...??
  • ??
  • class?LoadProgramException?extends?Exception?{??
  • ????public?LoadProgramException(String?msg,?Throwable?cause)?{??
  • ????????super(msg,?cause);??
  • ????}??
  • ????//?...??
  • }??
  • 注意:LoadProgramException構(gòu)造函數(shù)的第一個參數(shù)是代表原因,用于組成異常鏈,異常鏈?zhǔn)且环N機制,異常轉(zhuǎn)譯時,保存原來的異常,這樣當(dāng)這個異常再被轉(zhuǎn)譯時,還會被保存,于是就成了一條鏈了,包含了所有的異常,所以你可以看到這樣的異常打印: [plain]?view plaincopy print?
  • Exception?in?thread?"main"?java.lang.NoClassDefFoundError:?graphics/shapes/Square??
  • ????at?Main.main(Main.java:7)??
  • Caused?by:?java.lang.ClassNotFoundException:?graphics.shapes.Square??
  • ????at?java.net.URLClassLoader$1.run(URLClassLoader.java:366)??
  • ????at?java.net.URLClassLoader$1.run(URLClassLoader.java:355)??
  • ????at?java.security.AccessController.doPrivileged(Native?Method)??
  • ????at?java.net.URLClassLoader.findClass(URLClassLoader.java:354)??
  • ????at?java.lang.ClassLoader.loadClass(ClassLoader.java:424)??
  • ????at?sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:308)??
  • ????at?java.lang.ClassLoader.loadClass(ClassLoader.java:357)??
  • ????...?1?more??
  • 這個異常鏈中就是包含了兩個異常,最前面是頂級異常,后面再打印一個Cause by,然后再打印低一層異常,直到打印完所有的異常。

    另外,主流程中還有一個播放流程也可以定義一個播放異常的類,再做這樣的轉(zhuǎn)譯處理,但是,如果流程多,是不是得寫多個異常類呢,有人建議是每個包定義一個異常類,但并不是絕對的,這個細粒度還要根據(jù)具體的程序邏輯來決定,這種把握能力就要靠經(jīng)驗了,這可能就是架構(gòu)師的過人之處了。

    四、改拋為運行時異常:這個很好玩,也是一條很方便的處理手法(我常用,我用這個還發(fā)現(xiàn)了一個Android系統(tǒng)的bug),即當(dāng)你捕獲到異常時,重新拋出,這跟轉(zhuǎn)譯很相似,有一點區(qū)別,這里拋的是運行時異常,而轉(zhuǎn)譯拋的是編譯時異常。那什么時候使用這個手法呢?簡單的說就是當(dāng)某個異常出現(xiàn)時,你必須讓程序掛掉。解釋一下:如果某個異常情況一旦出現(xiàn),程序便無法繼續(xù)執(zhí)行,而且你明確知道本方法和上層邏輯做不出任何有意義的處理,你只能讓程序退出。所以你就拋一個運行時異常讓程序掛掉。舉個例子,比如在加密通信中,服務(wù)器捕獲到了一個非法數(shù)據(jù)異常,這是無法恢復(fù)的,而且就是拋一運行異常,讓線程掛掉,連接便會自動中斷。

    五、記錄并消耗掉異常:這個手法就是把異常記錄下來(到文件或控制臺)然后忽略掉異常,有可能隨后就讓本方法返回null,這個手法一般用在不是很嚴(yán)重的異常,相當(dāng)于是warning級別的錯誤,出現(xiàn)這個異常對程序的執(zhí)行可能影響不太,比如程序的某個偏好設(shè)置文件(如窗口位置,最近文件等)損壞,但這個文件信息很少,程序只要使用默認(rèn)配置即可。


    有沒必要顯示捕獲運行時異常

    運行時異常一般是不需要捕獲的,因為它的目的就是讓程序在無法恢復(fù)時掛掉,但是也有特殊需求,比如你要收集所有的未捕獲異常記錄,可能用于統(tǒng)計,也可能用于將來調(diào)試。還有其它原因使你不想讓程序直接掛掉,比如你想把友好信息告訴用戶。


    什么時候需要拋異常

    馬上就要討論如何拋異常了,但在必須先知道,什么時候需要拋異常,簡單的說就是遇到一個異常情況,這是一個模棱兩可的問題,就像美不美這個問題一樣,我?guī)追N說法,你看你能理解哪一種,一種是正常情況的反面,即非正常情況,那什么是非正常情況呢,這也是仁者見仁,智者見智,比如說讀到文件尾,這個算正常還是異常呢,都說得過去,所以這里給一個判斷方法做為參考,如果是一個典型情況,就不當(dāng)成是異常,所以讀到文件尾就沒有被當(dāng)成一個異常,返回了-1。還有一種說法是,程序執(zhí)行的必要條件不能成立,使得本方法無法繼續(xù)履行自己的職責(zé)。這兩種說法都不錯,你都可以用,而且覆蓋了大部分情況。


    何時選用編譯時異常:編譯時異常是Java特有的,其它語言沒有,剛出來時很流行,所以你可以看到流處理包里充斥著IOException,但經(jīng)過多年的使用,有人覺得編譯時異常是一種實驗性錯誤,應(yīng)該完全丟棄,說這個話的人就是《Think In Java》的一書的作者Eckel,我認(rèn)為這種說法太絕對了,關(guān)于這個是與否也有很大的爭論。《Effective Java》一書的作者則認(rèn)為應(yīng)避免不必要的編譯時異常,因為你拋編譯時異常會給強制要求調(diào)用者捕獲,這會增加他的負擔(dān),我是這一觀點的支持者。那到底何時拋編譯時異常呢?當(dāng)你發(fā)現(xiàn)一個異常情況時,檢查這兩個條件,為真時選用編譯時異常:一、如果調(diào)用者可以恢復(fù)此異常情況,二、如果調(diào)用者不能恢復(fù),但能做出有意義的事,如轉(zhuǎn)譯等。如果你不確定調(diào)用者能否做出有意義的事,就別使編譯時異常,免得被抱怨。還有一條原則,應(yīng)盡最大可能使用編譯時異常來代替錯誤碼,這條也是編譯時異常設(shè)計的目的。另外,必須注意使用編譯時異常的目的是為了恢復(fù)執(zhí)行,所以設(shè)計異常類的時候,應(yīng)提供盡量多的異常數(shù)據(jù),以便于上層恢復(fù),比如一個解析錯誤,可以在設(shè)計的異常類寫幾個變量來存儲異常數(shù)據(jù):解析出錯的句子的內(nèi)容,解析出錯句子的行號,解析出錯的字符在行中的位置。這些信息可能幫助調(diào)用恢復(fù)程序。


    何時選用運行時異常:首先,運行時異??隙ㄊ遣豢苫謴?fù)的異常,否則按上段方法處理。這個不可恢復(fù)指的是運行時期不可恢復(fù),如果可以修改源代碼來避免本異常的發(fā)生呢,那說明這是一個編程錯誤,對于編程錯誤,一定要拋運行時異常,編程錯誤一般可以通過修改代碼來永久性避免該異常,所以這種情況應(yīng)該讓程序掛掉,相當(dāng)于爆出一個bug,從而提醒程序員修改代碼。這種編程錯誤可以總結(jié)一下,API是調(diào)用者與實現(xiàn)者之間的契約,調(diào)用者必須遵守契約,比如傳入的參數(shù)不允許為空,這一點是隱含契約,沒必要明確寫出來的,如果違反契約,實現(xiàn)者就可以拋運行時異常,讓程序掛掉以提醒調(diào)用者。

    其它情況是否應(yīng)使用運行時異常,上面提到過,就是誰都無能為力的異常情況,還有就是你不確定到底能不能恢復(fù),除此之外,你可以這樣判斷:如果你希望程序掛掉,就用運行時異常。需要說明的是,請盡量使用系統(tǒng)自帶異常,而不是新寫。網(wǎng)上還有一條建議是使用運行時異常時, 一定要將所有可能的異常寫進文檔。這認(rèn)為只要把不常用的寫上即可,像NullPointException每個方法都有可能拋,但沒必要每個方法都寫說明。


    將編譯時異常重構(gòu)成運行時異常

    你可能手頭上有一份以前的代碼,大量的使有了編譯時異常,但很多都是沒有必要的編譯時異常,導(dǎo)致調(diào)用上不方便,《Effective Java》里有一種方法可以將編譯時異常轉(zhuǎn)為運行時異常:將原來拋編譯時異常的方法,拆成兩個方法,其中一個是用來指示異常是否為發(fā)生,即將以下代碼:

    [java]?view plaincopy print?
  • //?Invocation?with?checked?exception??
  • try?{??
  • obj.action(args);??
  • }?catch(TheCheckedException?e)?{??
  • //?Handle?exceptional?condition??
  • ...??
  • }??
  • 改為這樣: [java]?view plaincopy print?
  • //?Invocation?with?state-testing?method?and?unchecked?exception??
  • if?(obj.actionPermitted(args))?{??
  • obj.action(args);??
  • }?else?{??
  • //?Handle?exceptional?condition??
  • ...??
  • }??
  • 步驟是:1)將原來方法foo的異常申明刪掉,并在實現(xiàn)里面改拋為運行時異常;2)添加一個方法isFoo,返回一個布爾值指示是否會有異常情況出現(xiàn);3)在foo調(diào)用前加一個if語句,判斷isFoo的返回值,如果為真才調(diào)用foo,否則不調(diào)用;4)刪掉調(diào)用處的try-catch。


    UI層處理異常的注意點

    UI層和其下邏輯層的區(qū)別是UI層的出錯信息是被用戶看,而其下層邏層出錯信息是被程序員看到,用戶可不希望看一個打印的異常棧,更不希望程序無緣無故掛掉,用戶希望看到友好的提示信息。為到達這一目的,我們可以設(shè)一個屏障,屏障可以捕獲所有遺漏的異常,從而阻止程序直接掛掉,屏障當(dāng)然恢復(fù)不了運行,但可以記錄錯誤便于日后調(diào)試,還可以輸出友好信息給用戶。Spring和Struts就有這樣的處理。

    還有一點需要注意,用戶的傳入?yún)?shù)出現(xiàn)非法的概率很高,所以控制層接受到參數(shù)時一定要校驗,而不是原封不動的傳到其低層模塊。


    經(jīng)歷了一周的熬夜,總算把異常處理總結(jié)歸納成文了,但由于文章太長,肯定有一些錯誤和語言不精煉的地方,我會仔細檢察并及時改正,希望本文對大家有一定的幫助。


    附錄

    在我查過的資料中,以《Effective Java》書中對異常處理設(shè)計的研究得最系統(tǒng),本文很多思想來自于它,下面我把其中的幾條原則翻譯(非直譯)并貼上:

    第57條:只對異常情況使用異常。(說明:即不要用異常處理控制正常程序流)。

    第58條:對可恢復(fù)異常使用編譯時異常,對編程錯誤使用運行時異常。

    第59條:應(yīng)避免不必要的編譯時異常:如果調(diào)用者即使合理的使用API也不能避免異常的發(fā)生,并且調(diào)用者可以對捕獲的異常做出有意義的處理,才使用編譯時異常。

    第60條:應(yīng)偏好使用自帶異常

    第61條:拋出的異常應(yīng)適合本層抽象(就是上面說的轉(zhuǎn)譯)

    第62條:把方法可能拋的所有異常寫入文檔,包括運行時異常

    第63條:用異常類記錄的信息要包含失敗時的數(shù)據(jù)

    第64條:力求失敗是原子化的(解釋:就是如果調(diào)用一個方法發(fā)生了異常,就應(yīng)該使對象返回調(diào)用前的狀態(tài))

    第65條:不要忽略異常

    總結(jié)

    以上是生活随笔為你收集整理的Java异常处理终结篇——如何进行Java异常处理设计的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。