1. 程式人生 > >Java IO流中的異常處理以及自定義異常例項

Java IO流中的異常處理以及自定義異常例項

文章目錄

異常

1、 Throwable類
 a) 嚴重問題:Error,比如說記憶體不夠,一般程式中不進行處理
 b) 問題:Exception
  i. 編譯期問題:不是RunTimeException的異常,不處理編譯不能通過,因此必須處理
  ii. 執行期問題:是RunTimeException,程式碼中不夠嚴謹導致
  iii. 編譯期異常和執行期異常區別:
   1. 編譯期異常:Java程式必須顯示處理,否則程式就會發生錯誤,無法通過編譯.
   2. 執行期異常:無需顯示處理,也可以和編譯時異常一樣處理
 c) 如果程式出現問題,但是不進行任何處理,JVM會預設進行處理,將異常的名稱,
  原因及出現的問題等資訊輸出在控制檯,同時會結束程式,不再執行下面的程式。
 d) 如何處理異常?
  i. 單個異常
   try…catch…finally
   格式
    try {可能出現問題的程式碼(越少越好)}
    catch(異常名變數){針對問題的處理}
    finally{釋放資源}
  ii. 多個異常
   1、格式
    try {可能出現問題的程式碼(越少越好)}
    catch(異常名變數){針對問題的處理}
    catch(異常名變數){針對問題的處理}
    catch(異常名變數){針對問題的處理}
    …
    finally{釋放資源}
    注意事項
    a、一旦try裡面出現第一個異常就會把此異常丟擲去,和catch裡面的異常進行匹配,
     當匹配成功後執行完此catch內部的語句,繼續執行try… catch…finally後面的語句。
    b、當只知道出現異常,但不具體知道什麼異常時可以用catch(Exception e) 來進行匹配,
     這時無論任何異常都可以處理,但是如果可以明確就別這樣用。
   2、格式:try {可能出現問題的程式碼(越少越好)}
     catch(異常名變數|異常名變數|異常名變數|…){針對問題的處理}
     finally{釋放資源}
     注意事項
      a、針對catch後面的所有異常,處理方式都是一致的,
      b、多個異常必須是平級關係。

2、 throws異常
 a) 將自己處理不了的異常程式碼在方法上宣告,告訴呼叫者,此處程式有問題
 b) 格式:
  i. throws 異常類名,異常變數名,…可以跟一個異常,也可以跟多個異常
  ii. 注意此格式必須跟在方法的括號後面。
  iii. 注意儘量不要在main方法上丟擲異常,
 c) 如果是編譯期異常的丟擲,必須要通過throws來丟擲
  如果是執行期異常的丟擲,可以通過throws丟擲,也可以不丟擲。
3、 throws和throw的區別
 a) throws
  i. 用在方法聲明後,跟的是異常類名
  ii. 可以丟擲多個異常名,用逗號隔開
  iii. 表示丟擲異常,由該方法的呼叫者處理
  iv. throws表示出現異常的一種可能性,並不一定會發生這些異常。
 b) throw
  i. 用在方法體內部,跟的是異常物件名
  ii. 只能丟擲一個異常物件名
  iii. 表示丟擲異常,由方法體內的語句處理
  iv. throw丟擲異常,執行throw則一定丟擲了某種異常
4、 異常應該如何處理
 a) 如果該功能內部可以將問題處理,用try
 b) 如果處理不了,交由呼叫者處理,這時用throws
 c) 區別
  i. 後續程式需要繼續執行用try
  ii. 後續程式不需要運行了就用throws
5、 異常中的常用方法:
 a) public String getMessage() 獲取異常資訊,返回字串,並列印。
 b) public String toString() 獲取異常類名和異常資訊,返回字串並列印。
 c) public void printStackTrace()獲取異常類名和異常資訊,以及異常在程式中的位置,
   並在控制檯打印出來。
 d) public void printStackTrace(PrintStream s)用此方法將異常內容儲存在檔案中。
6、 finally
 a) finally控制的語句體一定會執行,但是如果在執行到finally之前Jvm退出了,就不會執行了,
  常用於釋放資源
 b) final、finally、finalize的區別
  i. final:最終的意思,可以修飾類,成員變數,成員方法
   1. 修飾類:類不能被繼承
   2. 修飾成員變數:變數是常量
   3. 修飾方法:方法不能被重寫
  ii. finally:異常處理的一部分,用於釋放資源
   一般來說,此處的程式碼肯定執行,但是如果在執行到finally之前Jvm退出了則不會執行
  iii. finalize:Object類的一個方法,用於垃圾回收
 c) 如果catch裡面有return語句,finally裡面的程式碼還會執行嗎?
  finally裡面的程式碼會執行,且執行完之後再執行catch中的return語句,
  注意:當執行到catch時catch中的return語句已經形成,裡面的值不會因為finally語句而更改。
  finally執行時特殊情況的例項在下面給出
7、 自定義異常
 a) 自定義異常類必須是繼承自Exception或者RuntimeException
 b) 自定義異常的例項在下面給出
8、 異常的注意事項
 a) 子類重寫父類方法時,子類的方法必須與父類丟擲相同的異常或者父類異常的子類。
 b) 如果父類丟擲了多個異常,子類重寫父類時,只能丟擲相同的異常或者父類異常的子集。
 c) 如果被重寫的方法沒有異常丟擲,那麼子類的方法絕對不可以丟擲異常,
  如果子類方法內有異常發生,那麼子類只能使用try,不能使用throws

自定義異常例項

測試程式碼

package test01_exception;

import java.util.Scanner;

public class Demo {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		System.out.println("請輸入一個數");
		int i=sc.nextInt();
		sc.close();
		Teacher t=new Teacher();
		try {
			t.check(i);
		} catch
(MyException e) { e.printStackTrace(); } System.out.println(); System.out.println("您輸入的是:"+i); } }
package test01_exception;
//如果是MyException繼承的是Exception需要通過throws丟擲
public class Teacher {
	public void check(int score) throws MyException {
		if(score<0||score>100) {
			System.out.println("輸入不合法");
			throw new MyException("你輸入的值不在規定範圍內");
			
		}else {
			System.out.println("輸入合法");
		}
	}
}
//如果是執行期異常(MyException繼承的是RuntimeException)不需要丟擲
//public class Teacher {
//	public void check(int score){
//		if(score<0||score>100) {
//			throw new MyException();
//			
//		}else {
//			System.out.println("請繼續輸入");
//		}
//	}
//}

自定義異常

package test01_exception;

public class MyException extends Exception{
	/**
	 * 
	 */
	//此處有兩個構造方法,如果丟擲異常時建立帶參構造方法物件,字串s會被顯示在控制檯異常處理結果
	private static final long serialVersionUID = 1L;
	public MyException() {
		
	}
	public MyException(String s) {
		super(s);
	}
	
	
}
//public class MyException extends RuntimeException{
//
//}

輸出樣式
在這裡插入圖片描述

finally中特殊情況例項

程式碼
主要是測試了finally語句塊中不同位置return的返回情況

package test15_finally;

public class FinallyDemo {
	public static void main(String[] args) {
		System.out.println(test());
	}

	private static int test() {
		int a=10;
		try {
			a=a/0;
		} catch (ArithmeticException e) {
			
			a=100;
//如果此處有退出的話則不會進入finally語句
			//System.exit(0);			
	
//此處雖然有return但是由於有finally需要先執行finally語句再進行返回操作
//但是此處的return語句在執行catch語句塊時就已經確定了return的值,
//執行finally並不影響此處的return值
			return a;
			
		}finally {
			
			System.out.println(a);
			a=20;
			System.out.println(a);

//如果此處有return的話就直接返回了,不會再進入catch中的return語句
			//return a;
		}
		
		return a;
	}
}

輸出樣式
在這裡插入圖片描述