JAVA異常處理

異常是程序中的一些錯誤敛摘,但并不是所有的錯誤都是異常门烂,并且錯誤有時候是可以避免的。

比如說兄淫,你的代碼少了一個分號屯远,那么運行出來結果是提示是錯誤 java.lang.Error;如果你用System.out.println(11/0)捕虽,那么你是因為你用0做了除數(shù)氓润,會拋出 java.lang.ArithmeticException 的異常。

創(chuàng)一個小群薯鳍,供大家學習交流聊天

如果有對學JAVA方面有什么疑惑問題的,或者有什么想說的想聊的大家可以一起交流學習一起進步呀挨措。

也希望大家對學JAVA能夠持之以恒

JAVA愛好群挖滤,

如果你想要學好JAVA最好加入一個組織,這樣大家學習的話就比較方便浅役,還能夠共同交流和分享資料斩松,給你推薦一個學習的組織:快樂學習JAVA組織 可以點擊組織二字,可以直達


異常發(fā)生的原因有很多觉既,通常包含以下幾大類:

用戶輸入了非法數(shù)據(jù)惧盹。

要打開的文件不存在。

網(wǎng)絡通信時連接中斷瞪讼,或者JVM內(nèi)存溢出钧椰。

這些異常有的是因為用戶錯誤引起,有的是程序錯誤引起的符欠,還有其它一些是因為物理錯誤引起的嫡霞。-

要理解Java異常處理是如何工作的,你需要掌握以下三種類型的異常:

檢查性異常:最具代表的檢查性異常是用戶錯誤或問題引起的異常希柿,這是程序員無法預見的诊沪。例如要打開一個不存在文件時,一個異常就發(fā)生了曾撤,這些異常在編譯時不能被簡單地忽略端姚。

運行時異常:?運行時異常是可能被程序員避免的異常。與檢查性異常相反挤悉,運行時異辰ヂ悖可以在編譯時被忽略。

錯誤:?錯誤不是異常,而是脫離程序員控制的問題橄仆。錯誤在代碼中通常被忽略剩膘。例如,當棧溢出時盆顾,一個錯誤就發(fā)生了怠褐,它們在編譯也檢查不到的。

Exception 類的層次

所有的異常類是從 java.lang.Exception 類繼承的子類您宪。

Exception 類是 Throwable 類的子類奈懒。除了Exception類外,Throwable還有一個子類Error 宪巨。

Java 程序通常不捕獲錯誤磷杏。錯誤一般發(fā)生在嚴重故障時,它們在Java程序處理的范疇之外捏卓。

Error 用來指示運行時環(huán)境發(fā)生的錯誤极祸。

例如,JVM 內(nèi)存溢出怠晴。一般地遥金,程序不會從錯誤中恢復。

異常類有兩個主要的子類:IOException 類和 RuntimeException 類蒜田。

在 Java 內(nèi)置類中(接下來會說明)稿械,有大部分常用檢查性和非檢查性異常。

Java 內(nèi)置異常類

Java 語言定義了一些異常類在 java.lang 標準包中冲粤。

標準運行時異常類的子類是最常見的異常類美莫。由于 java.lang 包是默認加載到所有的 Java 程序的,所以大部分從運行時異常類繼承而來的異常都可以直接使用梯捕。

Java 根據(jù)各個類庫也定義了一些其他的異常厢呵,下面的表中列出了 Java 的非檢查性異常。

異常描述

ArithmeticException當出現(xiàn)異常的運算條件時傀顾,拋出此異常述吸。例如,一個整數(shù)"除以零"時锣笨,拋出此類的一個實例蝌矛。

ArrayIndexOutOfBoundsException用非法索引訪問數(shù)組時拋出的異常。如果索引為負或大于等于數(shù)組大小错英,則該索引為非法索引入撒。

ArrayStoreException試圖將錯誤類型的對象存儲到一個對象數(shù)組時拋出的異常。

ClassCastException當試圖將對象強制轉(zhuǎn)換為不是實例的子類時椭岩,拋出該異常茅逮。

IllegalArgumentException拋出的異常表明向方法傳遞了一個不合法或不正確的參數(shù)璃赡。

IllegalMonitorStateException拋出的異常表明某一線程已經(jīng)試圖等待對象的監(jiān)視器,或者試圖通知其他正在等待對象的監(jiān)視器而本身沒有指定監(jiān)視器的線程献雅。

IllegalStateException在非法或不適當?shù)臅r間調(diào)用方法時產(chǎn)生的信號碉考。換句話說,即 Java 環(huán)境或 Java 應用程序沒有處于請求操作所要求的適當狀態(tài)下挺身。

IllegalThreadStateException線程沒有處于請求操作所要求的適當狀態(tài)時拋出的異常侯谁。

IndexOutOfBoundsException指示某排序索引(例如對數(shù)組、字符串或向量的排序)超出范圍時拋出章钾。

NegativeArraySizeException如果應用程序試圖創(chuàng)建大小為負的數(shù)組墙贱,則拋出該異常。

NullPointerException當應用程序試圖在需要對象的地方使用?null?時贱傀,拋出該異常

NumberFormatException當應用程序試圖將字符串轉(zhuǎn)換成一種數(shù)值類型惨撇,但該字符串不能轉(zhuǎn)換為適當格式時,拋出該異常府寒。

SecurityException由安全管理器拋出的異常魁衙,指示存在安全侵犯。

StringIndexOutOfBoundsException此異常由?String?方法拋出株搔,指示索引或者為負剖淀,或者超出字符串的大小。

UnsupportedOperationException當不支持請求的操作時邪狞,拋出該異常。

下面的表中列出了 Java 定義在 java.lang 包中的檢查性異常類茅撞。

異常描述

ClassNotFoundException應用程序試圖加載類時帆卓,找不到相應的類,拋出該異常米丘。

CloneNotSupportedException當調(diào)用?Object?類中的?clone?方法克隆對象剑令,但該對象的類無法實現(xiàn)?Cloneable?接口時,拋出該異常拄查。

IllegalAccessException拒絕訪問一個類的時候吁津,拋出該異常。

InstantiationException當試圖使用?Class?類中的?newInstance?方法創(chuàng)建一個類的實例堕扶,而指定的類對象因為是一個接口或是一個抽象類而無法實例化時碍脏,拋出該異常。

InterruptedException一個線程被另一個線程中斷稍算,拋出該異常典尾。

NoSuchFieldException請求的變量不存在

NoSuchMethodException請求的方法不存在

異常方法

下面的列表是 Throwable 類的主要方法:

序號方法及說明

1public String getMessage()

返回關于發(fā)生的異常的詳細信息。這個消息在Throwable 類的構造函數(shù)中初始化了糊探。

2public Throwable getCause()

返回一個Throwable 對象代表異常原因钾埂。

3public String toString()

使用getMessage()的結果返回類的串級名字河闰。

4public void printStackTrace()

打印toString()結果和棧層次到System.err,即錯誤輸出流褥紫。

5public StackTraceElement [] getStackTrace()

返回一個包含堆棧層次的數(shù)組姜性。下標為0的元素代表棧頂,最后一個元素代表方法調(diào)用堆棧的棧底髓考。

6public Throwable fillInStackTrace()

用當前的調(diào)用棧層次填充Throwable 對象棧層次部念,添加到棧層次任何先前信息中穿稳。

捕獲異常

使用 try 和 catch 關鍵字可以捕獲異常描验。try/catch 代碼塊放在異炒艮龋可能發(fā)生的地方也拜。

try/catch代碼塊中的代碼稱為保護代碼换薄,使用 try/catch 的語法如下:

try

{

? // 程序代碼

}catch(ExceptionName e1)

{

? //Catch 塊

}

Catch 語句包含要捕獲異常類型的聲明呐赡。當保護代碼塊中發(fā)生一個異常時副签,try 后面的 catch 塊就會被檢查论衍。

如果發(fā)生的異常包含在 catch 塊中奶是,異常會被傳遞到該 catch 塊楣责,這和傳遞一個參數(shù)到方法是一樣。

實例

下面的例子中聲明有兩個元素的一個數(shù)組聂沙,當代碼試圖訪問數(shù)組的第三個元素的時候就會拋出一個異常秆麸。

ExcepTest.java 文件代碼:

// 文件名 : ExcepTest.javaimport java.io.*;public class ExcepTest{

? public static void main(String args[]){? ? ? try{? ? ? ? int a[] = new int[2];

? ? ? ? System.out.println("Access element three :" + a[3]);

? ? ? }catch(ArrayIndexOutOfBoundsException e){? ? ? ? System.out.println("Exception thrown? :" + e);

? ? ? }? ? ? System.out.println("Out of the block");

? }}

以上代碼編譯運行輸出結果如下:

Exception thrown? :java.lang.ArrayIndexOutOfBoundsException: 3

Out of the block

多重捕獲塊

一個 try 代碼塊后面跟隨多個 catch 代碼塊的情況就叫多重捕獲。

多重捕獲塊的語法如下所示:

try{? // 程序代碼}catch(異常類型1 異常的變量名1){? // 程序代碼}catch(異常類型2 異常的變量名2){? // 程序代碼}catch(異常類型2 異常的變量名2){? // 程序代碼}

上面的代碼段包含了 3 個 catch塊及汉。

可以在 try 語句后面添加任意數(shù)量的 catch 塊沮趣。

如果保護代碼中發(fā)生異常,異常被拋給第一個 catch 塊坷随。

如果拋出異常的數(shù)據(jù)類型與 ExceptionType1 匹配房铭,它在這里就會被捕獲。

如果不匹配温眉,它會被傳遞給第二個 catch 塊缸匪。

如此,直到異常被捕獲或者通過所有的 catch 塊类溢。

實例

該實例展示了怎么使用多重 try/catch凌蔬。

try {? ? file = new FileInputStream(fileName);

? ? x = (byte) file.read();} catch(FileNotFoundException f) { // Not valid!? ? f.printStackTrace();

? ? return -1;} catch(IOException i) {? ? i.printStackTrace();

? ? return -1;}

throws/throw 關鍵字:

如果一個方法沒有捕獲到一個檢查性異常,那么該方法必須使用 throws 關鍵字來聲明闯冷。throws 關鍵字放在方法簽名的尾部砂心。

也可以使用 throw 關鍵字拋出一個異常,無論它是新實例化的還是剛捕獲到的蛇耀。

下面方法的聲明拋出一個 RemoteException 異常:

import java.io.*;public class className{? public void deposit(double amount) throws RemoteException? {? ? // Method implementation? ? throw new RemoteException();

? }? //Remainder of class definition}

一個方法可以聲明拋出多個異常计贰,多個異常之間用逗號隔開。

例如蒂窒,下面的方法聲明拋出 RemoteException 和 InsufficientFundsException:

import java.io.*;public class className{? public void withdraw(double amount) throws RemoteException,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? InsufficientFundsException? {? ? ? // Method implementation? }? //Remainder of class definition}

finally關鍵字

finally 關鍵字用來創(chuàng)建在 try 代碼塊后面執(zhí)行的代碼塊躁倒。

無論是否發(fā)生異常荞怒,finally 代碼塊中的代碼總會被執(zhí)行。

在 finally 代碼塊中秧秉,可以運行清理類型等收尾善后性質(zhì)的語句褐桌。

finally 代碼塊出現(xiàn)在 catch 代碼塊最后,語法如下:

try{? // 程序代碼}catch(異常類型1 異常的變量名1){? // 程序代碼}catch(異常類型2 異常的變量名2){? // 程序代碼}finally{? // 程序代碼}

實例

ExcepTest.java 文件代碼:

public class ExcepTest{? public static void main(String args[]){? ? int a[] = new int[2];

? ? try{? ? ? System.out.println("Access element three :" + a[3]);

? ? }catch(ArrayIndexOutOfBoundsException e){? ? ? System.out.println("Exception thrown? :" + e);

? ? }? ? finally{? ? ? a[0] = 6;

? ? ? System.out.println("First element value: " +a[0]);

? ? ? System.out.println("The finally statement is executed");

? ? }? }}

以上實例編譯運行結果如下:

Exception thrown? :java.lang.ArrayIndexOutOfBoundsException: 3

First element value: 6

The finally statement is executed

注意下面事項:

catch 不能獨立于 try 存在象迎。

在 try/catch 后面添加 finally 塊并非強制性要求的荧嵌。

try 代碼后不能既沒 catch 塊也沒 finally 塊。

try, catch, finally 塊之間不能添加任何代碼砾淌。

聲明自定義異常

在 Java 中你可以自定義異常啦撮。編寫自己的異常類時需要記住下面的幾點。

所有異常都必須是 Throwable 的子類汪厨。

如果希望寫一個檢查性異常類赃春,則需要繼承 Exception 類。

如果你想寫一個運行時異常類劫乱,那么需要繼承 RuntimeException 類织中。

可以像下面這樣定義自己的異常類:

class MyException extends Exception{}

只繼承Exception 類來創(chuàng)建的異常類是檢查性異常類。

下面的 InsufficientFundsException 類是用戶定義的異常類衷戈,它繼承自 Exception狭吼。

一個異常類和其它任何類一樣,包含有變量和方法殖妇。

實例

以下實例是一個銀行賬戶的模擬刁笙,通過銀行卡的號碼完成識別,可以進行存錢和取錢的操作谦趣。

InsufficientFundsException.java 文件代碼:

// 文件名InsufficientFundsException.javaimport java.io.*;

//自定義異常類疲吸,繼承Exception類public class InsufficientFundsException extends Exception{? //此處的amount用來儲存當出現(xiàn)異常(取出錢多于余額時)所缺乏的錢? private double amount;

? public InsufficientFundsException(double amount)? {? ? this.amount = amount;

? }

? public double getAmount()? {? ? return amount;

? }}

為了展示如何使用我們自定義的異常類,

在下面的 CheckingAccount 類中包含一個 withdraw() 方法拋出一個 InsufficientFundsException 異常蔚润。

CheckingAccount.java 文件代碼:

// 文件名稱 CheckingAccount.javaimport java.io.*;

//此類模擬銀行賬戶public class CheckingAccount{? //balance為余額磅氨,number為卡號? private double balance;

? private int number;

? public CheckingAccount(int number)? {? ? ? this.number = number;

? }? //方法:存錢? public void deposit(double amount)? {? ? ? balance += amount;

? }? //方法:取錢? public void withdraw(double amount) throws? ? ? ? ? ? ? ? ? ? ? ? ? ? ? InsufficientFundsException? {? ? ? if(amount <= balance)? ? ? {? ? ? ? balance -= amount;

? ? ? }? ? ? else? ? ? {? ? ? ? double needs = amount - balance;

? ? ? ? throw new InsufficientFundsException(needs);

? ? ? }? }? //方法:返回余額? public double getBalance()? {? ? ? return balance;

? }? //方法:返回卡號? public int getNumber()? {? ? ? return number;

? }}

下面的 BankDemo 程序示范了如何調(diào)用 CheckingAccount 類的 deposit() 和 withdraw() 方法尺栖。

BankDemo.java 文件代碼:

//文件名稱 BankDemo.javapublic class BankDemo{? public static void main(String [] args)? {? ? ? CheckingAccount c = new CheckingAccount(101);

? ? ? System.out.println("Depositing $500...");

? ? ? c.deposit(500.00);

? ? ? try? ? ? {? ? ? ? System.out.println("\nWithdrawing $100...");

? ? ? ? c.withdraw(100.00);

? ? ? ? System.out.println("\nWithdrawing $600...");

? ? ? ? c.withdraw(600.00);

? ? ? }catch(InsufficientFundsException e)? ? ? {? ? ? ? System.out.println("Sorry, but you are short $"? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? + e.getAmount());

? ? ? ? e.printStackTrace();

? ? ? }? ? }}

編譯上面三個文件嫡纠,并運行程序 BankDemo,得到結果如下所示:

Depositing $500...

Withdrawing $100...

Withdrawing $600...

Sorry, but you are short $200.0

InsufficientFundsException

? ? ? ? at CheckingAccount.withdraw(CheckingAccount.java:25)

? ? ? ? at BankDemo.main(BankDemo.java:13)

通用異常

在Java中定義了兩種類型的異常和錯誤延赌。

JVM(Java虛擬機)?異常:由 JVM 拋出的異吵担或錯誤。例如:NullPointerException 類挫以,ArrayIndexOutOfBoundsException 類者蠕,ClassCastException 類。

程序級異常:由程序或者API程序拋出的異常掐松。例如 IllegalArgumentException 類踱侣,IllegalStateException 類粪小。

?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市抡句,隨后出現(xiàn)的幾起案子探膊,更是在濱河造成了極大的恐慌,老刑警劉巖待榔,帶你破解...
    沈念sama閱讀 221,576評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件逞壁,死亡現(xiàn)場離奇詭異,居然都是意外死亡锐锣,警方通過查閱死者的電腦和手機腌闯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來雕憔,“玉大人姿骏,你說我怎么就攤上這事¢佘裕” “怎么了工腋?”我有些...
    開封第一講書人閱讀 168,017評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長畅卓。 經(jīng)常有香客問我擅腰,道長,這世上最難降的妖魔是什么翁潘? 我笑而不...
    開封第一講書人閱讀 59,626評論 1 296
  • 正文 為了忘掉前任趁冈,我火速辦了婚禮,結果婚禮上拜马,老公的妹妹穿的比我還像新娘渗勘。我一直安慰自己,他們只是感情好俩莽,可當我...
    茶點故事閱讀 68,625評論 6 397
  • 文/花漫 我一把揭開白布旺坠。 她就那樣靜靜地躺著,像睡著了一般扮超。 火紅的嫁衣襯著肌膚如雪取刃。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,255評論 1 308
  • 那天出刷,我揣著相機與錄音璧疗,去河邊找鬼。 笑死馁龟,一個胖子當著我的面吹牛崩侠,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播坷檩,決...
    沈念sama閱讀 40,825評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼却音,長吁一口氣:“原來是場噩夢啊……” “哼改抡!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起系瓢,我...
    開封第一講書人閱讀 39,729評論 0 276
  • 序言:老撾萬榮一對情侶失蹤雀摘,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后八拱,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體阵赠,經(jīng)...
    沈念sama閱讀 46,271評論 1 320
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,363評論 3 340
  • 正文 我和宋清朗相戀三年肌稻,在試婚紗的時候發(fā)現(xiàn)自己被綠了清蚀。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,498評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡爹谭,死狀恐怖枷邪,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情诺凡,我是刑警寧澤东揣,帶...
    沈念sama閱讀 36,183評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站腹泌,受9級特大地震影響嘶卧,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜凉袱,卻給世界環(huán)境...
    茶點故事閱讀 41,867評論 3 333
  • 文/蒙蒙 一芥吟、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧专甩,春花似錦钟鸵、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至种樱,卻和暖如春蒙袍,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背缸托。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評論 1 272
  • 我被黑心中介騙來泰國打工左敌, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留瘾蛋,地道東北人俐镐。 一個月前我還...
    沈念sama閱讀 48,906評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像哺哼,于是被迫代替她去往敵國和親佩抹。 傳聞我的和親對象是個殘疾皇子叼风,可洞房花燭夜當晚...
    茶點故事閱讀 45,507評論 2 359

推薦閱讀更多精彩內(nèi)容

  • 初識異常(Exception) 比如我們在取數(shù)組里面的某個值得時候,經(jīng)常會出現(xiàn)定義的取值范圍超過了數(shù)組的大小棍苹,那么...
    iDaniel閱讀 1,871評論 1 2
  • 異常分類 Java將異常分為兩種无宿,Checked異常和Runtime異常。Java認為Checked異常都是可以在...
    LLorenzo閱讀 720評論 0 1
  • Java異常類型 所有異常類型都是Throwable的子類枢里,Throwable把異常分成兩個不同分支的子類Erro...
    予別她閱讀 932評論 0 2
  • 2.JAVA異常 異常指不期而至的各種狀況孽鸡,如:文件找不到、網(wǎng)絡連接失敗栏豺、非法參數(shù)等彬碱。異常是一個事件,它發(fā)生在程...
    青城樓主閱讀 561評論 0 0
  • 近日從電視上看到我們天津許多地方政府聯(lián)合商家舉辦各種公益小活動奥洼,雖然是為了促進地方經(jīng)濟發(fā)展巷疼,但從市民方來看...
    禮仁君閱讀 376評論 0 0