天天看點

Java異常處理機制很有意思

版權聲明:歡迎轉載,請注明沉默王二原創。 https://blog.csdn.net/qing_gee/article/details/43015379

前言:在網絡上看到一篇《

深入了解Java異常處理機制

》,看完感覺自己也有一點小想法,的确在很多Java學者的眼裡,異常處理機制不就是try catch finally嗎,有啥好了解,很多時候,我也經常忽略這方面的内容,感覺沒什麼有意思的,那麼我們來紮個小馬步吧。

1.經過對原作者的例子改造

package mwq;

public class T1 {

	public static void main(String[] args) {
		boolean b = true;
		try {
			b = tb1();
		} catch (ArithmeticException e) {
			System.out.println("main catch the value of b : " + b);
			b = false;
			throw e;
		} finally {
			System.out.println("main finally b : " + b);
		}

	}

	public static boolean tb1() throws ArithmeticException {
		boolean b = true;

		try {
			if (!tb2()) {
				return false;
			}
		} catch (ArithmeticException e) {
			System.out.println("tb1 catch the value of b : " + b);
			b = false;
			throw e;
		} finally {
			System.out.println("tb1 finally b : " + b);
		}

		return b;
	}

	@SuppressWarnings("finally")
	public static boolean tb2() throws ArithmeticException {
		boolean b = true;

		try {
			System.out.println(1 / 0);
		} catch (ArithmeticException e) {
			System.out.println("tb2 catch the value of b : " + b);
			b = false;
			throw e;
		} finally {
			System.out.println("tb2 finally b : " + b);
			return b;
		}
	}

}
      

2.我自己感覺有意思的例子

package mwq;

public class T {

	public static void main(String[] args) {
		try {
			System.out.println(1 / 0);
			System.out.println("ccccccccccccccccccc");
		} catch (ArithmeticException e) {
			System.out.println(1 / 0);
			System.out.println("aaaaaaaaaaaaaaaaaaa");
		} finally {
			System.out.println(1 / 0);
			System.out.println("bbbbbbbbbbbbbbbb");
		}
	}

}
      

第一個例子就不多講了,如果你的答案如下

tb2 catch the value of b : true
tb2 finally b : false
tb1 finally b : true
main finally b : false      

那麼,你就不需要你就可以不看原作者的例子了,不過可以讀讀他那麼基礎的理論知識。

對于第二個例子,在很多實際的應用中用到的很多,正常流程中,就如try語句,大多數情況下,我們很自覺的加上對應的catch語句,至少是catch Exception,那麼這個是沒有問題,但是很多時候,我們的catch語句中也有一些邏輯處理,并非簡單的輸出錯誤日志,假如我們在catch中再出現錯誤時,很多時候,catch中我們多數認為是正常的代碼,于是我們不再對catch中語句進行catch捕獲,那麼按照上面的例子,你的答案是這樣的嗎?

Exception in thread "main" java.lang.ArithmeticException: / by zero
	at mwq.T.main(T.java:13)
      

錯誤時代碼的13行,為什麼不是第10行代碼的錯誤呢,因為finally的作用就是,無論catch有沒有捕獲到錯誤,finally都要執行,雖然代碼的第10行已經抛出異常了,但是程式會先執行finally而不是将catch的錯誤在堆棧中列印出來,因為finally中已經出錯了,程式要先把finally中的錯誤進行處理,然後程式将錯誤列印出來後,就終止了,這個時候第10行的錯誤也就不會輸出了,假如程式是這樣的

package mwq;

public class T {

	public static void main(String[] args) {
		try {
			System.out.println(1 / 0);
			System.out.println("ccccccccccccccccccc");
		} catch (ArithmeticException e) {
			System.out.println(1 / 0);
			System.out.println("aaaaaaaaaaaaaaaaaaa");
		} finally {
			System.out.println("bbbbbbbbbbbbbbbb");
		}
	}

}      

那麼此時你認為結果會是怎樣呢,結果有兩種

bbbbbbbbbbbbbbbb
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at mwq.T.main(T.java:10)
      
Exception in thread "main" java.lang.ArithmeticException: / by zero
	at mwq.T.main(T.java:10)
bbbbbbbbbbbbbbbb
      

為什麼會有兩種結果呢,大多數情況下,都會先輸出bbbbbbbbbbbbbbbbb,然而由于out對象也是輸入輸出流,JVM在進行處理的時候,少數情況下會将錯誤資訊先列印出來,而後再将out對象的bbbbbbbbbbbbbbb輸出出來,這可能是線程排程的原因,但是請小夥伴們懷疑我這種結論,因為我并沒有證明是這種情況。

總結:總體而言,我感覺Java異常處理機制是很有意思,而不簡單。