java異常處理01-異常分類

java異常處理01-異常分類

什么是Java異常?

當(dāng)Java程序的正常行為被意外行為中斷時季率,會發(fā)生故障茸塞。這種故障被稱為異常躲庄。例如,程序嘗試打開文件以讀取其內(nèi)容钾虐,但該文件不存在將產(chǎn)生異常噪窘。Java將異常分為幾種類型,所以讓我們考慮每一種類型效扫。

檢查異常

Java將(例如FileNotFoundException, IOException)引起的異常分類為已檢查的異常效览。Java編譯器會檢查這些異常,并且在異常發(fā)生的位置要求進(jìn)行捕獲處理或者向上拋出(throws)荡短。需要注意的是檢查異常屬于編譯器的行為丐枉,要求你必須在代碼中捕獲或向上拋出(throws)

運(yùn)行時(非檢查)異常

例如程序進(jìn)行強(qiáng)制轉(zhuǎn)換(cast)掘托,這種可能存在轉(zhuǎn)換失敗的異常就是另一種異常瘦锹。即運(yùn)行時異常(RuntimeException)。和檢查不同,編譯器不會檢查你在代碼中是否進(jìn)行處理或拋出弯院。運(yùn)行時異常通常來自編寫的不良代碼辱士,因此應(yīng)由程序員修復(fù)。

錯誤(Error)

指一些非常嚴(yán)重听绳,通常無法進(jìn)行修正必須要重啟程序的異常颂碘。例如, 嘗試從JVM分配內(nèi)存椅挣,但沒有足夠的可用內(nèi)存來滿足請求(OutOfMemoryError)头岔。運(yùn)行時嘗試調(diào)用加載類文件但類文件但無法找到時(NoClassDefFoundError)。對于錯誤您永遠(yuǎn)不應(yīng)該嘗試捕獲并自己處理錯誤鼠证,因為JVM可能已經(jīng)無法從中恢復(fù)正常峡竣。

Throwable及其子類

Java提供了表示不同類型異常的類層次結(jié)構(gòu)。java.lang包的Throwable類是所有異常類的超類量九。

/
└────Throwable
     ├────Error
     │    ├────NoClassDefFoundError
     │    └────OutOfMemoryError
     └────Exception
          ├────RuntimeException
          │    ├────IllegalArgumentException
          │    └────NullPointerException
          ├────FileNotFoundException
          └────IOException
 (注: 該圖使用https://github.com/harbby/gadtry Graph功能繪制)

注意:通常您不應(yīng)該以任何方式捕獲和處理Throwable适掰。

Exception類

Throwable有兩個直接的子類。其中一個子類是Exception荠列。Java提供了許多直接子類的異常類Exception类浪。比如:

  • SQLException 表示發(fā)生了jdbc異常,來自java.sql包中

  • IOException 表示發(fā)生了I/O異常肌似,來自java.io包中

注意费就,每個Exception子類名稱都以Exception單詞結(jié)尾。該約定使得易于識別該類異常锈嫩。

您可能想自定義使用自己的Exception檢查異常受楼。下面自定義示例:

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

    public MyException(String message, Throwable cause)
    {
        super(message, cause);
    }

    public MyException(Throwable cause)
    {
        super(cause);
    }
}

Error類

Throwable另一個直接的子類是Error垦搬,描述了一個合理的應(yīng)用程序不應(yīng)該嘗試處理的嚴(yán)重問題 - 例如內(nèi)存不足溢出呼寸,棧溢出,或者嘗試加載無法找到的類猴贰。例如:

  • OutOfMemoryError 內(nèi)存溢出
  • StackOverflowError 棧溢出
  • NoClassDefFoundError 嘗試加載無法找到的類時觸發(fā)

注意:通常您不應(yīng)該以任何方式捕獲和處理Error類異常对雪。

RuntimeException類

RuntimeException異常或其子類實(shí)例化是未經(jīng)檢查的異常米绕。直接父類是Exception瑟捣。RuntimeException和其分類Exception 聲明相同的構(gòu)造函數(shù)(具有相同的參數(shù)列表)。它通常表示一個可能由不良代碼引起的運(yùn)行時異常栅干。下面是它的一些示例:

  • NullPointerException 空指針異常迈套,java最常見異常。過多的該異常通常意味您需要提高代碼編寫技巧碱鳞。
  • IllegalArgumentException 驗證異常桑李,通常表示參數(shù)非法或不正確的狀態(tài)。
  • ClassCastException 類型轉(zhuǎn)換異常

NullPointerException異常優(yōu)化:

  1. 嘗試使用java.util.Optional<T>作為方法返回值,使用Optional.empty()取代return null贵白;
  2. 使用將字符串放在前面 "str".equals(arg)
  3. 做好方法或構(gòu)造函數(shù)的入?yún)z查率拒。this.args = Objects.requireNonNull(inArgs, "inArgs is null");
  4. 返回空集合而不是null。return new String[0] or return Collections.emptyMap()
  5. 方法入?yún)⒑头祷厥褂?long,int 而非包裝類 Intger,Long

異常拋出

C語言通常return全局錯誤變量來通常調(diào)用者禁荒。而java則使用拋出異常對象來通知調(diào)用者猬膨。了解如何以及何時拋出異常是Java編程一個非常重要技能。通常您只拋出ExceptionRuntimeException的子類實(shí)例化的對象呛伴。拋出異常有兩個步驟。

  1. 使用throw new 異常語句拋出異常對象磷蜀。
  2. 在方法上使用throws 異常語句告知編譯器(對于檢查異常這是必須的)。

throw拋出異常:

throw new SQLException();
throw new FileNotFoundException("not find file " + fileName);

異常拋出是指將異常對象從當(dāng)前方法拋出到JVM污它。然后JVM會在異常表中查找合適異常處理邏輯(catch)。如何沒有找到則JVM會退出當(dāng)前方法的調(diào)用棧庶弃,從上級調(diào)用者(方法)的異常表中繼續(xù)尋找衫贬。如果找到它將使用該處理代碼進(jìn)行處理異常。如果JVM最后在main()方法的異常表中依然沒有找到合適處理邏輯(catch)那么JVM將會發(fā)出消息-1然后退出歇攻。

注意: 異常處理通常非常昂貴,您不該在任何時候使用異常處理邏輯來處理您的正常業(yè)務(wù)

throws告知編譯器:

從方法中拋出檢查異常時葬毫,需要在方法上添加拋出標(biāo)志來通知編譯器。

public static void main(String[] args) throws SQLException {}

總結(jié)

該篇文檔總結(jié)java異常的分類和各自的特點(diǎn)屡穗。下面是一些關(guān)鍵點(diǎn)總結(jié):

  • 強(qiáng)制你處理或拋出檢查異常屬于編譯器的行為贴捡,對于它編譯器要求你必須在代碼中捕獲或向上拋出(throws)。

  • 永遠(yuǎn)不要試圖catch Error錯誤嘗試捕獲并自己處理錯誤村砂,因為JVM可能已經(jīng)無法從中恢復(fù)正常烂斋。

  • 永遠(yuǎn)不要以任何方式直接catch捕獲和處理Throwable, 因為Error是它子類础废。

  • 異常處理通常代價非常昂貴,不要試圖用來處理您的正常業(yè)務(wù)评腺。

  • 過多的NullPointerException異常意味著你需要提高代碼編寫技巧。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蝶念,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子祸轮,更是在濱河造成了極大的恐慌,老刑警劉巖适袜,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異售貌,居然都是意外死亡疫萤,警方通過查閱死者的電腦和手機(jī)颂跨,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門恒削,熙熙樓的掌柜王于貴愁眉苦臉地迎上來尾序,“玉大人钓丰,你說我怎么就攤上這事每币。” “怎么了兰怠?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長肥橙。 經(jīng)常有香客問我掖举,道長快骗,這世上最難降的妖魔是什么塔次? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任名秀,我火速辦了婚禮,結(jié)果婚禮上继榆,老公的妹妹穿的比我還像新娘。我一直安慰自己略吨,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布鞠苟。 她就那樣靜靜地躺著,像睡著了一般当娱。 火紅的嫁衣襯著肌膚如雪考榨。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天河质,我揣著相機(jī)與錄音,去河邊找鬼云头。 笑死,一個胖子當(dāng)著我的面吹牛溃槐,可吹牛的內(nèi)容都是我干的科吭。 我是一名探鬼主播昏滴,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼谣殊,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姻几?” 一聲冷哼從身側(cè)響起势告,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎咱台,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體春贸,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年逸嘀,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片厘熟。...
    茶點(diǎn)故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡维哈,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出阔挠,到底是詐尸還是另有隱情,我是刑警寧澤购撼,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布迂求,位于F島的核電站碾盐,受9級特大地震影響揩局,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凌盯,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望阐滩。 院中可真熱鬧县忌,春花似錦掂榔、人聲如沸症杏。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽喧伞。三九已至绩郎,卻和暖如春翁逞,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挖函。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留怨喘,地道東北人津畸。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓必怜,卻偏偏與公主長得像,于是被迫代替她去往敵國和親梳庆。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,941評論 2 355