異常是程序中的一些錯誤,但並非全部的錯誤都是異常,而且錯誤有時候是能夠避免的。java
好比說,你的代碼少了一個分號,那麼運行出來結果是提示是錯誤 java.lang.Error;若是你用System.out.println(11/0),那麼你是由於你用0作了除數,會拋出 java.lang.ArithmeticException 的異常。
創一個小羣,供你們學習交流聊天
若是有對學JAVA方面有什麼疑惑問題的,或者有什麼想說的想聊的你們能夠一塊兒交流學習一塊兒進步呀。
也但願你們對學JAVA可以鍥而不捨
JAVA愛好羣,
若是你想要學好JAVA最好加入一個組織,這樣你們學習的話就比較方便,還可以共同交流和分享資料,給你推薦一個學習的組織:快樂學習JAVA組織 能夠點擊組織二字,能夠直達
異常發生的緣由有不少,一般包含如下幾大類:程序員
用戶輸入了非法數據。
要打開的文件不存在。
網絡通訊時鏈接中斷,或者JVM內存溢出。
這些異常有的是由於用戶錯誤引發,有的是程序錯誤引發的,還有其它一些是由於物理錯誤引發的。-
要理解Java異常處理是如何工做的,你須要掌握如下三種類型的異常:數組
檢查性異常:最具表明的檢查性異常是用戶錯誤或問題引發的異常,這是程序員沒法預見的。例如要打開一個不存在文件時,一個異常就發生了,這些異常在編譯時不能被簡單地忽略。
運行時異常: 運行時異常是可能被程序員避免的異常。與檢查性異常相反,運行時異常能夠在編譯時被忽略。
錯誤: 錯誤不是異常,而是脫離程序員控制的問題。錯誤在代碼中一般被忽略。例如,當棧溢出時,一個錯誤就發生了,它們在編譯也檢查不到的。
Exception 類的層次
全部的異常類是從 java.lang.Exception 類繼承的子類。安全
Exception 類是 Throwable 類的子類。除了Exception類外,Throwable還有一個子類Error 。網絡
Java 程序一般不捕獲錯誤。錯誤通常發生在嚴重故障時,它們在Java程序處理的範疇以外。函數
Error 用來指示運行時環境發生的錯誤。學習
例如,JVM 內存溢出。通常地,程序不會從錯誤中恢復。this
異常類有兩個主要的子類:IOException 類和 RuntimeException 類。spa
在 Java 內置類中(接下來會說明),有大部分經常使用檢查性和非檢查性異常。線程
Java 內置異常類
Java 語言定義了一些異常類在 java.lang 標準包中。
標準運行時異常類的子類是最多見的異常類。因爲 java.lang 包是默認加載到全部的 Java 程序的,因此大部分從運行時異常類繼承而來的異常均可以直接使用。
Java 根據各個類庫也定義了一些其餘的異常,下面的表中列出了 Java 的非檢查性異常。
異常 描述
ArithmeticException 當出現異常的運算條件時,拋出此異常。例如,一個整數"除以零"時,拋出此類的一個實例。
ArrayIndexOutOfBoundsException 用非法索引訪問數組時拋出的異常。若是索引爲負或大於等於數組大小,則該索引爲非法索引。
ArrayStoreException 試圖將錯誤類型的對象存儲到一個對象數組時拋出的異常。
ClassCastException 當試圖將對象強制轉換爲不是實例的子類時,拋出該異常。
IllegalArgumentException 拋出的異常代表向方法傳遞了一個不合法或不正確的參數。
IllegalMonitorStateException 拋出的異常代表某一線程已經試圖等待對象的監視器,或者試圖通知其餘正在等待對象的監視器而自己沒有指定監視器的線程。
IllegalStateException 在非法或不適當的時間調用方法時產生的信號。換句話說,即 Java 環境或 Java 應用程序沒有處於請求操做所要求的適當狀態下。
IllegalThreadStateException 線程沒有處於請求操做所要求的適當狀態時拋出的異常。
IndexOutOfBoundsException 指示某排序索引(例如對數組、字符串或向量的排序)超出範圍時拋出。
NegativeArraySizeException 若是應用程序試圖建立大小爲負的數組,則拋出該異常。
NullPointerException 當應用程序試圖在須要對象的地方使用 null 時,拋出該異常
NumberFormatException 當應用程序試圖將字符串轉換成一種數值類型,但該字符串不能轉換爲適當格式時,拋出該異常。
SecurityException 由安全管理器拋出的異常,指示存在安全侵犯。
StringIndexOutOfBoundsException 此異常由 String 方法拋出,指示索引或者爲負,或者超出字符串的大小。
UnsupportedOperationException 當不支持請求的操做時,拋出該異常。
下面的表中列出了 Java 定義在 java.lang 包中的檢查性異常類。
異常 描述
ClassNotFoundException 應用程序試圖加載類時,找不到相應的類,拋出該異常。
CloneNotSupportedException 當調用 Object 類中的 clone 方法克隆對象,但該對象的類沒法實現 Cloneable 接口時,拋出該異常。
IllegalAccessException 拒絕訪問一個類的時候,拋出該異常。
InstantiationException 當試圖使用 Class 類中的 newInstance 方法建立一個類的實例,而指定的類對象由於是一個接口或是一個抽象類而沒法實例化時,拋出該異常。
InterruptedException 一個線程被另外一個線程中斷,拋出該異常。
NoSuchFieldException 請求的變量不存在
NoSuchMethodException 請求的方法不存在
異常方法
下面的列表是 Throwable 類的主要方法:
序號 方法及說明
1 public String getMessage()
返回關於發生的異常的詳細信息。這個消息在Throwable 類的構造函數中初始化了。
2 public Throwable getCause()
返回一個Throwable 對象表明異常緣由。
3 public String toString()
使用getMessage()的結果返回類的串級名字。
4 public void printStackTrace()
打印toString()結果和棧層次到System.err,即錯誤輸出流。
5 public StackTraceElement [] getStackTrace()
返回一個包含堆棧層次的數組。下標爲0的元素表明棧頂,最後一個元素表明方法調用堆棧的棧底。
6 public Throwable fillInStackTrace()
用當前的調用棧層次填充Throwable 對象棧層次,添加到棧層次任何先前信息中。
捕獲異常
使用 try 和 catch 關鍵字能夠捕獲異常。try/catch 代碼塊放在異常可能發生的地方。
try/catch代碼塊中的代碼稱爲保護代碼,使用 try/catch 的語法以下:
try
{
// 程序代碼
}catch(ExceptionName e1)
{
//Catch 塊
}
Catch 語句包含要捕獲異常類型的聲明。當保護代碼塊中發生一個異常時,try 後面的 catch 塊就會被檢查。
若是發生的異常包含在 catch 塊中,異常會被傳遞到該 catch 塊,這和傳遞一個參數到方法是同樣。
實例
下面的例子中聲明有兩個元素的一個數組,當代碼試圖訪問數組的第三個元素的時候就會拋出一個異常。
ExcepTest.java 文件代碼:
// 文件名 : ExcepTest.java
import 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 語句後面添加任意數量的 catch 塊。
若是保護代碼中發生異常,異常被拋給第一個 catch 塊。
若是拋出異常的數據類型與 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 關鍵字用來建立在 try 代碼塊後面執行的代碼塊。
不管是否發生異常,finally 代碼塊中的代碼總會被執行。
在 finally 代碼塊中,能夠運行清理類型等收尾善後性質的語句。
finally 代碼塊出如今 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 類來建立的異常類是檢查性異常類。
下面的 InsufficientFundsException 類是用戶定義的異常類,它繼承自 Exception。
一個異常類和其它任何類同樣,包含有變量和方法。
實例
如下實例是一個銀行帳戶的模擬,經過銀行卡的號碼完成識別,能夠進行存錢和取錢的操做。
InsufficientFundsException.java 文件代碼:
// 文件名InsufficientFundsException.java
import java.io.*;
//自定義異常類,繼承Exception類
public class InsufficientFundsException extends Exception
{
//此處的amount用來儲存當出現異常(取出錢多於餘額時)所缺少的錢
private double amount;
public InsufficientFundsException(double amount)
{
this.amount = amount;
}
public double getAmount()
{
return amount;
}
}
爲了展現如何使用咱們自定義的異常類,
在下面的 CheckingAccount 類中包含一個 withdraw() 方法拋出一個 InsufficientFundsException 異常。
CheckingAccount.java 文件代碼:
// 文件名稱 CheckingAccount.java
import 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 程序示範瞭如何調用 CheckingAccount 類的 deposit() 和 withdraw() 方法。
BankDemo.java 文件代碼:
//文件名稱 BankDemo.java
public 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 類。