1. 程式人生 > >Java新手:異常和遞迴

Java新手:異常和遞迴

異常

異常是指我們在寫程式碼時出現的編譯或者執行時的錯誤。

  1. 異常的體系結構:
    1、Throwable是Java語言中所有錯誤或異常的超類,Throwable有兩個子類,Error和Exception,Error是指出現的不能夠處理的嚴重問題,Exception是樂意處理的異常問題。
    2、在Exception的子類有一個RuntimeException,是那些可能在java虛擬機器正常執行期間丟擲的異常的超類,RuntimeException和他所有的子類異常,都屬於執行時的異常,在編譯時期可以自由選擇處理或者不處理。
    3、執行時期異常的特點:
    方法中丟擲執行時期異常,方法定義中無需throws宣告,呼叫者也無需處理此異常
    執行時期異常一旦發生,需要程式人員修改原始碼.
    4、編譯時期異常:是Exception的子類,非RuntimeExcpetion的子類,在編譯時期必須處理。
  2. 異常的處理方式
    jvm處理異常的方式:如果我們沒有自己處理異常,jvm或幫助我們處理,會把異常的型別,原因還有位置顯示在命令列;還會終止程式,異常後面的程式碼不在執行。例如除以0.
    1、捕獲處理
    捕獲是指對可能出現的異常進行指定方法的處理捕獲。
    try {
    有可能出現問題的程式碼;
    } catch(ArithmeticException e) {
    處理異常;
    }finally{
    釋放資源;
    清理垃圾;
    }
    注意:finally:組合try…catch使用,用於釋放資源等收尾工作,無論try…catch語句如何執行,finally的程式碼一定會執行。
public static void main(String[] args) {
		try{
			System.out.println(1);
			System.out.println(2/0);
			System.out.println(2);
		}catch(ArithmeticException e){
			System.out.println("除數不能為零");
		}
		System.out.println(3);
	}

輸出結果:

1
除數不能為零
3

注意:try…catch的執行順序:
首先執行try語句,如果發現異常,異常下面的程式碼不在執行,直接跳入catch語句中,catch語句結束後,整個try…catch結束;如果沒有發現異常,try語句執行結束後,try…catch直接結束,不在執行catch語句

public static void main(String[] args) {
		FileWriter fw = null;
		try {
			//System.out.println(2 / 0);
			fw = new FileWriter("a.txt");
			fw.write("hello");
			fw.write("world");
			//System.out.println(2 / 0);
			fw.write("java");
			//fw.close();
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			//釋放資源
			try {
				if(fw != null) {
					fw.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

2、丟擲去
當我們不想處理異常,或者沒有能力處理的時候,我們可以選擇丟擲異常,誰呼叫方法誰處理異常,使用關鍵字throws在方法的宣告出丟擲異常

public static void main(String[] args) throws Exception {
		function();
}
public static void function() throws Exception{
	FileWriter fw = new FileWriter("a.txt");
}

注意:
throws使用:
許可權修飾符 返回值型別 方法名(形參列表)throws 異常型別1,異常型別2….{ }

  1. 多異常處理
    對異常進行異常檢測,對每種異常資訊進行不同的捕獲異常。
    try{
    throw new Exception();//產生異常,直接捕獲處理
    }catch(XxxException e){
    //處理方式
    }catch(YyyException e){
    //處理方式
    }catch(ZzzException e){
    //處理方式
    }
public static void main(String[] args) {
		try{
			String s = null;
			System.out.println(s.length());
			int[] arr = new int[5];
			System.out.println(arr[6]);
			System.out.println(2 / 0);
		} catch(ArrayIndexOutOfBoundsException e) {
			System.out.println("出現數組越界了");
		} catch(NullPointerException e) {
			System.out.println("出現空指標了");
		}catch(Exception e) {
			System.out.println("出現異常了");
		} 
	}

結果:出現空指標了,因為出現空指標異常後,try就不再往下走了,直接跳到catch中。
注意:這種異常處理方式,要求多個catch中的異常不能相同,多個catch之間可以有子父類,平級之間沒有順序關係,如果有子父類,父類異常必須放在後面。

  1. Throwable的常用方法:
    1、String getMessage() 返回此 throwable 的詳細訊息字串
    2、 String toString() 返回此 throwable 的簡短描述
    3、 void printStackTrace() 列印異常的堆疊的跟蹤資訊
public static void main(String[] args) {
		try{
			System.out.println(2/0);
		}catch(ArithmeticException e){
			System.out.println("e.getMessage()="+e.getMessage());
			System.out.println("e.toString()="+e.toString());
			e.printStackTrace();
		}
	}

結果:

e.getMessage()=/ by zero
e.toString()=java.lang.ArithmeticException: / by zero
java.lang.ArithmeticException: / by zero
	at com.ArrayListTest.RecurrenceDemo.main(RecurrenceDemo.java:8)
  1. 自定義異常
    1、throws:處理異常的一種方式,把異常丟擲,由呼叫者來處理
    throw:製造異常的方式,並且結束方法
    2、自定義一個執行時異常:寫一個類去繼承Exception或者RuntimeException,然後實現多個構造即可。
public class myException extends RuntimeException{
	public myException() {
		super();
		// TODO Auto-generated constructor stub
	}
	public myException(String message) {
		super(message);
		// TODO Auto-generated constructor stub
	}
}

使用該異常類

public static void main(String[] args) {
		try{
			checkScore(110);
		}catch(Exception e){
			e.printStackTrace();
		}
	}
	public static void checkScore(int score)throws Exception{
		if(score<0||score>100)
			throw new myException("考試成績不符合要求");
		System.out.println("考試成績符合要求");
	}

結果:

com.ArrayListTest.myException: 考試成績不符合要求
	at com.ArrayListTest.RecurrenceDemo.checkScore(RecurrenceDemo.java:16)
	at com.ArrayListTest.RecurrenceDemo.main(RecurrenceDemo.java:9)

注意:如果丟擲(throw)的是編譯時期異常,必須在方法宣告處丟擲(throws)

遞迴

  1. 遞迴就是指在當前方法內呼叫自己的這種現象,把大問題拆成小問題,再把小問題拆成更多的小問題,然後隨著把更多小問題的解決,大問題也隨之解決了。
  2. 遞迴的注意事項:
    1、遞迴一定要有出口,避免記憶體溢位。
    2、遞迴次數不宜過多,避免記憶體溢位。
  3. 斐波那契數列
    有一對小兔子,從出生後第3個月起每個月都生一對兔子,小兔子長到第三個月後每個月又生一對兔子,假如兔子都不死,問第二十個月的兔子對數。
    規律:除了第一個月和第二個月以外,其餘每個月都是前兩個月之和。
月份 對數
第1個月 1
第二個月 1
第三個月 2
第四個月 3
第五個月 5
第六個月 8
第七個月 13
public class RecurrenceDemo {
	public static void main(String[] args) {
	int result = method(20);
	System.out.println("結果是"+result);
	}
	public static int method(int n){
		if(n==1||n==2){
			return 1;
		}else{
			return method(n-1)+method(n-2);
		}
	}
}

結果是:結果是6765