throw關鍵字
當程序發生異常而無法處理的時候,會拋出對應的異常對象。
初次之外,在某些時刻我們可能會想要自行拋出異常,例如在異常處理結束后,再將異常
拋出,讓下一層異常處理塊來捕捉,若想要自行拋出異常,可以使用throw關鍵字,
並生成指定的異常對象拋出。
throw是一個動作,是拋出異常。
throw new ArithmeticExeption(),主動拋出異常。
throws關鍵字
throws用來在方法聲明的同時,標明方法可能拋出的異常。定義方法可能會拋出的異常。
告訴該方法在運行的時候可能會出現這樣的異常,在代碼中一定要對相應的異常進行處理。
只有一類異常,拋出的時候方法可以不用聲明,就是RuntimeException異常。
main()方法時處理異常的最后一個陣地。
package exception; /** * 使用當前類測試異常的拋出 * @author 小明 * */ public class Person { private int age; public int getAge() { return age; } public void setAge(int age) throws Exception{ if(age <0 || age > 100){ //throw new RuntimeException("年齡不合法"); /** * 當一個方法中使用throw拋出一個異常時 * 就要在當前方法上使用throws聲明該異常的拋出以便通知調用 * 在調用當前方法時要處理異常。 * 只有RuntimeException及其子類在拋出時 * 編譯器不要求必須寫throws聲明,其他異常則必須聲明 * 否則編譯不通過。 */ throw new Exception("年齡不合法"); //拋出異常的目的就是為了告訴外界,這里可能會拋出異常 //如果這里用try-catch //寫throw的目的就是為了告訴外界這里可能會有問題 //處理別人拋出的異常時,才用try-catch或throws /** * 為什么在以前寫流的時候一定要捕獲異常, * 那是因為流的構造方法里就拋出了異常,在創建的時候,我們必須捕獲這個 * 異常,處理異常。 */ } this.age = age; } }
package exception; /** * 測試異常的拋出 * @author 小明 * */ public class ThrowDemo { public static void main(String[] args) { Person person = new Person(); /** * 通常一個方法拋出異常有兩種情況 * 1:方法當中遇到了滿足語法要求,但是不滿足 * 業務邏輯要求(下面的案例就是這種情況) * 2:方法中確實出現了異常,但是該異常不應當有該方法處理時, * 會拋出給調用者解決 */ /** * 碰到異常的時候,首先要知道是什么錯 * 異常:1.指定拋出的異常 * 2.將異常拋出給相應的方法,該方法沒有進行處理 * 找異常at語句從自己寫的類開始看 * 該方法沒有處理異常時,程序就被kill了。 */ try { person.setAge(1000); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(person.getAge()); } }
使用throws語句拋出異常的方法在被重寫的時候有一定的規則:
package exception; import java.awt.AWTException; import java.io.FileNotFoundException; import java.io.IOException; import java.sql.SQLException; /** * 子類重寫父類含有throws聲明異常拋出的方法時對throws * 的重寫規則 * @author 小明 * */ public class ThrowsDemo { public void dosome()throws IOException, AWTException { } //重寫時可以不再拋出任何異常 } class Son extends ThrowsDemo{ /** * 子類拋出的異常可以是父類拋出異常的子類型 * */ //和父類拋出相同的異常 // public void dosome()throws IOException, AWTException // { // // } // 不拋出異常 // public void dosome() // { // // } //拋出父類中拋出異常類的子類 // public void dosome()throws FileNotFoundException // { // // } //不能拋出額外異常。 // public void dosome()throws SQLException // { // // } //不能拋出比父類更高的異常類 // public void dosome()throws Exception // { // // } }
java異常可以分為可檢測異常,非檢測異常:
在java中只有RuntimeException及其子類是非檢測異常,其他都是檢測異常。
可檢測異常:可檢測異常經編譯器驗證,對於聲明拋出異常的任何方法,編譯器將強制執行處理貨聲明規則,不捕獲這個異常,編譯器就通不過,不允許編譯。
非檢測異常:非檢測異常不遵循處理或者聲明規則。在產生此類異常時,不一定非要采取適當
操作,編譯器不會檢查是否已經解決了這樣一個異常。
RuntimeException類屬於非檢測異常,因為普通JVM操作引起的運行時異常隨時可能發生,
此類異常一般是特定操作引發。但這些操作在java應用程序中會頻繁出現,因此它們不受編譯器檢查與處理或聲明規則的限制。
比如說最常見的異常--空指針異常就是非檢測異常,非檢測異常時不會拋出的。
還有下標越界,數字格式異常。
異常里最常用的方法:就printStackTrace()。輸出錯誤信息,有助於找到並解決錯誤。
自定義異常
目的:有時候java提供的異常不足以說明我們碰到的問題。
根據我們的需求拋出我們想要拋出的異常。主要我們是想根據拋出的異常類名知道程序到底拋出了什么樣的異常。通過異常的名字馬上就知道發生了什么問題,所以我們要自定義異常。
比如說年齡設定異常,java中沒有這樣的異常,所以我們要創建這樣的異常類。
package exception; /** * 年齡不合法異常 * * 自定義異常,通常用來說明我們程序中某個業務邏輯錯誤 * 因為java提供的異常基本上沒有實際項目中的業務錯誤 * 這是我們可以自行定義一個異常。 * @author 小明 * */ /** * 需要做幾件事 * 最重要就是異常類名字--要求見名知意 * @author 小明 * */ public class IIlegalAgeException extends Exception{ /** * */ private static final long serialVersionUID = 1L; //為什么要有這條語句 /** * 因為Exception繼承自Throwable,而Throwable實現了Serializable接口 * 實現了序列化接口就要有版本號 */ public IIlegalAgeException() { super(); // TODO Auto-generated constructor stub } public IIlegalAgeException(String arg0, Throwable arg1, boolean arg2, boolean arg3) { super(arg0, arg1, arg2, arg3); // TODO Auto-generated constructor stub } public IIlegalAgeException(String arg0, Throwable arg1) { super(arg0, arg1); // TODO Auto-generated constructor stub } public IIlegalAgeException(String arg0) { super(arg0); // TODO Auto-generated constructor stub } public IIlegalAgeException(Throwable arg0) { super(arg0); // TODO Auto-generated constructor stub } }
Person.java
package exception; /** * 使用當前類測試異常的拋出 * @author 小明 * */ public class Person { private int age; public int getAge() { return age; } public void setAge(int age) throws IIlegalAgeException{ if(age <0 || age > 100){ //throw new RuntimeException("年齡不合法"); /** * 當一個方法中使用throw拋出一個異常時 * 就要在當前方法上使用throws聲明該異常的拋出以便通知調用 * 在調用當前方法時要處理異常。 * 只有RuntimeException及其子類在拋出時 * 編譯器不要求必須寫throws聲明,其他異常則必須聲明 * 否則編譯不通過。 */ throw new IIlegalAgeException("年齡不合法"); //拋出異常的目的就是為了告訴外界,這里可能會拋出異常 //如果這里用try-catch //寫throw的目的就是為了告訴外界這里可能會有問題 //處理別人拋出的異常時,才用try-catch或throws /** * 為什么在以前寫流的時候一定要捕獲異常, * 那是因為流的構造方法里就拋出了異常,在創建的時候,我們必須捕獲這個 * 異常,處理異常。 */ } this.age = age; } }
ThrowDemo.java
package exception; /** * 測試異常的拋出 * @author 小明 * */ public class ThrowDemo { public static void main(String[] args) { Person person = new Person(); /** * 通常一個方法拋出異常有兩種情況 * 1:方法當中遇到了滿足語法要求,但是不滿足 * 業務邏輯要求(下面的案例就是這種情況) * 2:方法中確實出現了異常,但是該異常不應當有該方法處理時, * 會拋出給調用者解決 */ /** * 碰到異常的時候,首先要知道是什么錯 * 異常:1.指定拋出的異常 * 2.將異常拋出給相應的方法,該方法沒有進行處理 * 找異常at語句從自己寫的類開始看 * 該方法沒有處理異常時,程序就被kill了。 */ try { person.setAge(1000); } catch (IIlegalAgeException e) { //e.printStackTrace(); System.out.println("出錯了"); } System.out.println(person.getAge()); } }