java异常——异常分类+声明已检查异常+如何抛出异常+自定义异常类
【0】README
0.1) 本文描述+源代碼均 轉(zhuǎn)自 core java volume 1, 旨在理解 java異常——異常分類+聲明已檢查異常+如何拋出異常+自定義異常類 的相關(guān)知識;
0.2)異常處理的任務(wù): 就是將控制權(quán)從錯誤產(chǎn)生的地方轉(zhuǎn)移給能夠處理這種case 的錯誤處理器;
0.3)為了能夠在程序中處理異常情況, 必須研究程序中可能會出現(xiàn)的錯誤和問題,以及哪類問題需要關(guān)注:
- 0.3.1)用戶輸入錯誤:用戶輸入 URL , 而其語法卻不正確;
- 0.3.2)設(shè)備錯誤:硬件不總是讓它做什么,它就做什么, 比如打印機(jī)關(guān)掉了;
- 0.3.3)物理限制:磁盤滿了,可用存儲空間已被用完;
- 0.3.4)代碼錯誤:程序方法有可能無法正確執(zhí)行;
【1】異常分類
1.1)java中, 異常都是派生于 Throwable 類的一個實(shí)例: 且如果java內(nèi)置的異常類不能夠滿足需求,用戶可以自己創(chuàng)建異常類;(下圖顯示了 java異常層次結(jié)構(gòu)的簡化圖)
對上圖的分析(Analysis)
- A1)Error類層次結(jié)構(gòu):描述了java運(yùn)行時系統(tǒng)的內(nèi)部錯誤和資源耗盡錯誤, 這種case 很少出現(xiàn);
- A2)Exception層次結(jié)構(gòu):劃分成兩個分支的規(guī)則是: 由程序錯誤導(dǎo)致的異常屬于 RuntimeException, 而程序本身沒有問題, 但由于像 IO錯誤這類問題導(dǎo)致的異常屬于其他異常;
1.2)派生于RuntimeException 的異常包含下面幾種 Cases(運(yùn)行時異常的幾種 cases), 這屬于未檢查類異常(unchecked):
- C1)錯誤的類型轉(zhuǎn)換;
- C2)數(shù)組訪問越界;
- C3)訪問空指針;
1.3)不是派生于 RuntimeException 的異常包括:
- C1)試圖在文件尾部后面讀取數(shù)據(jù);
- C2)試圖打開一個不存在的文件;
- C3)試圖根據(jù)給定的字符串查找class 對象, 而這個字符串表示的類并不存在;
Attention)
- A1)如果出現(xiàn) RuntimeException 異常, 那么就一定是你的問題了, 這是一條相當(dāng)有道理的規(guī)則;
- A2)應(yīng)該通過檢測數(shù)組下標(biāo)是否越界來避免 ArrayIndexOutofBoundException 異常;應(yīng)該通過在變量使用前檢測是否為空來杜絕 NullPointerException 異常的發(fā)生;
1.4)異常分類:
- 1.4.1)未檢查異常(不需要throw 拋出的異常,這是程序運(yùn)行過程中出現(xiàn)的錯誤): java語言規(guī)范 派生于 Error類 或 RuntimeException類的所有異常稱為 未檢查異常(unchecked);
- 1.4.2)已檢查異常(需要顯式拋出的異常):所有其他的異常稱為 已檢查異常(checked);
【2】聲明已檢查異常
2.1)如果遇到了無法處理的case , java拋出一個異常, 這個道理很簡單: 一個方法不僅需要告訴編譯器將要返回什么值, 還要告訴編譯器有可能發(fā)生什么錯誤;例如, 一段讀取文件 的代碼知道有可能讀取的文件不存在, 或者內(nèi)容為null , 因此, 試圖處理文件信息的代碼就需要通知編譯器可能會拋出 IOException 類的異常;
2.2)方法應(yīng)該在其首部聲明所有可能拋出的 異常, 這樣可以從首部反映出這個方法可能拋出哪類已檢查異常:如,
, 如果上述代碼真的拋出了異常, 那么運(yùn)行時系統(tǒng)就會開始搜索異常處理器, 以便知道如何處理 FileNotFoundException 對象;
2.3)在自己編寫方法時, 不必將所有 可能拋出的異常全部都進(jìn)行聲明。 至于什么時候需要在方法中用 throws 子句聲明異常, 什么異常必須使用 throws 子句聲明, 需要記住下面遇到的 4種 Cases 應(yīng)該拋出異常:
- C1)調(diào)用一個拋出已檢查異常的方法, 例如, FileInputStream 構(gòu)造器;
- C2)程序運(yùn)行過程中發(fā)現(xiàn)錯誤, 并且利用 throw 語句拋出一個已檢查異常;
- C3)程序出現(xiàn)錯誤, 例如, a[-1]=0 會拋出一個 ArrayIndexOutOfBoundsException 這樣的未檢查異常;
C4) java 虛擬機(jī)和運(yùn)行時庫出現(xiàn)的內(nèi)部錯誤;
2.3.1)如果出現(xiàn)前兩種cases 之一, 則必須告訴調(diào)用這個方法的程序員有可能拋出異常。因為任何一個拋出異常的方法都有可能是一個死亡陷阱。如果沒有處理器捕獲這個異常, 當(dāng)前執(zhí)行的線程就會結(jié)束;
- 2.3.2)對于那些可能被其他人使用的 java方法, 應(yīng)該根據(jù)異常規(guī)范, 在方法的首部聲明這個方法可能拋出的異常;
- 2.3.3)如果一個方法有可能拋出多個已檢查異常, 那么就必須在方法的首部列出所有的異常類。每個異常類之間用逗號隔開:
- 2.3.4)但是,不需要 聲明java 的內(nèi)部錯誤, 即從Error 繼承的錯誤。因為任何程序代碼都具有拋出那些異常的潛能, 而我們對其沒有任何控制能力;
- 2.3.5)同樣, 也不應(yīng)該聲明從 RuntimeException 繼承的那些未檢查異常:(因為, 這些錯誤完全在我們的控制之下, 如果特別關(guān)注數(shù)組下標(biāo)引發(fā)的錯誤, 就應(yīng)該將更多的時間花在 修正程序的錯誤上, 而不是說明這些錯誤發(fā)生的可能性上) //bad style 錯誤的異常拋出格式(RuntimeException屬于未檢查類異常,是不需要throw 拋出的異常,這是程序運(yùn)行過程中出現(xiàn)的錯誤)
Conclusion)
- C1)總之, 一個方法必須 聲明 所有可能拋出的已檢查異常, 而未檢查異常要么不可控制(Error), 要么就應(yīng)該避免發(fā)生(RuntimeException)。 如果方法沒有聲明所有可能發(fā)生的已檢查異常, 編譯器就會給出一個錯誤消息;
- C2)當(dāng)然,除了聲明異常之外, 還可以捕獲異常, 這樣會使得異常不被拋出到方法之外,也不需要 throws 規(guī)范;(稍后, 我們來討論如何決定一個異常是被捕獲, 還是被拋出讓其他的處理器進(jìn)行處理)
Warning)
- W1)如果在子類中覆蓋了超類中的一個方法, 子類方法中聲明的已檢查異常不能比超類方法中聲明的異常更通用(也就是說, 子類方法中可以拋出更特定的異常, 或者根本不拋出任何異常)
W2)特別需要說明的是: 如果超類方法沒有拋出任何已檢查異常, 子類也不能拋出任何已檢查異常;
2.3.6)如果類中的一個方法聲明將會拋出一個異常, 而這個異常是某個特定類的實(shí)例時, 則這個方法就有可能拋出一個這個類的異常, 或者這個類的任意一個子類的異常;看個荔枝:
- 例如: FileInputStream 構(gòu)造器聲明將有可能拋出一個 IOException異常,然而并不知道具體是哪種IOException異常, 它既可能是 IOException異常,也可能是其子類的異常,例如, FileNotFoundException;
【3】如何拋出異常
3.1)首先要決定拋出什么類型異常 。如, EOFException異常描述為“在輸入過程中, 遇到了一個未預(yù)期的EOF后 的信號”;
3.2)下面拋出這個異常的語句:
- 3.2.1)EOFException類還有一個字符串參數(shù)的構(gòu)造器。這個構(gòu)造器更加詳細(xì)的描述異常出現(xiàn)的情況:
- 3.2.2)在以下cases 下, 一旦方法拋出異常, 這個方法就不可能返回到調(diào)用者了;
- case1)找到一個合適的異常類;
- case2)創(chuàng)建這個類的一個對象;
- case3)將對象拋出;
【4】創(chuàng)建異常類(自定義異常類)
4.1)我們需要做的只是:定義一個派生于Exception的類, 或者派生于Exception子類的類;
4.2)定義的類應(yīng)該包含兩個構(gòu)造器: 一個是默認(rèn)的構(gòu)造器, 另一個是帶有詳細(xì)描述信息的構(gòu)造器(超類Throwable 的toString 方法將會打印出這些詳細(xì)信息, 在調(diào)試中非常有用)
- 4.2.1)現(xiàn)在,就可以拋出自定義的異常類型了:
[API] java.lang.Throwable 1.0
- Throwable() :構(gòu)造一個新的 Throwable 對象, 這個對象沒有詳細(xì)的描述信息;
- Throwable(String msg):構(gòu)造一個新的 Throwable 對象, 這個對象包含詳細(xì)的描述信息;習(xí)慣上, 所有派生的異常類都支持一個默認(rèn)構(gòu)造器和一個帶有描述信息的構(gòu)造器;
- String getMessage(): 獲得Throwable 對象 的詳細(xì)描述信息;
總結(jié)
以上是生活随笔為你收集整理的java异常——异常分类+声明已检查异常+如何抛出异常+自定义异常类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 性能最强的集成显卡电脑(最强大的集成显卡
- 下一篇: 极品飞车怎么设置中文(极品飞车怎么设置中