【黑馬程序員濟南校區】java基礎:異常
Java運行時期發生的問題就是異常。
Java中運行時發生的除了異常Exception還有錯誤Error。
異常:通常發生可以有針對性的處理方式的。
錯誤:通常發生後不會有針對性的處理方式。
Error的發生往往都是系統級別的問題,都是jvm所在系統發生的並反饋給jvm的。
無法針對處理,只能修正代碼。
在編寫程序時,必須要考慮程序的問題情況。所以定義定義程序需要考慮程序的健壯性。加入一些邏輯性的判斷。
異常體系的特點:
異常體系中的所有類及其子類對象都具備可拋性。也就是說可以被throw和throws關鍵字所操作。
main方法是如何處理異常的。
A:在main裏面編寫代碼進行處理 B:交給jvm自己進行處理。采用的是jvm的默認處理方式。 其實就是相當於調用了異常對象的printStackTrace()方法。
Throwable類的學習
getMessage():獲取異常信息,返回字符串。
toString():獲取異常類名和異常信息,返回字符串。
printStackTrace():獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。
異常應用:
if(arr==null) //空指針拋出異常
{
thrownewNullPointerException("arr指向的數組不存在");
}
if(index<0|| index>=arr.length) // 角標越界拋出異常
{ thrownewArrayIndexOutOfBoundsException("錯誤的角標,"+index+"索引在數組中不存在"); }
if(age<0|| age>200) //無效參數拋出異常
{
thrownewIllegalArgumentException(age+",年齡數值非法");
}
自定義異常:
自定義異常被拋出,必須是繼承Throwable,或者繼承Throwable的子類。該對象才可以被throw拋出,
可以將自定義的異常繼承RuntimeException.在java虛擬機運行時異常以及其子類都無需進行聲明
classNoAgeException extendsRuntimeException
{ /* 為什麽要定義構造函數,因為看到Java中的異常描述類中有提供對問題對象的初始化方法。 */ NoAgeException() { super(); } NoAgeException(String message) { super(message);// 如果自定義異常需要異常信息,可以通過調用父類的帶有字符串參數的構造函數即可。 } }
原理異常分兩種:
1,編譯時異常(Java.lang.Excpetion):編譯器會檢測的異常。jvm認為程序本身有問題要進行聲明或者捕獲。
2,運行時異常(Java.lang.RuntimeExcpetion):編譯器不會檢測的異常。不需要聲明。聲明也可以,如果聲明了,無外乎就是讓調用者給出處理方式。
繼承Exception和繼承RuntimeExcpetion的區別:
Exception 類及其子類是 Throwable 的一種形式,它指出了合理的應用程序想要捕獲的條件。
//(該程序已經出現問題,Java認為這個程序本身存在隱患,需要捕獲或者聲明出來)
RuntimeException 是那些可能在 Java 虛擬機正常運行期間拋出的異常的超類。
可能在執行方法期間拋出但未被捕獲的 RuntimeException 的任何子類都無需在 throws 子句中進行聲明。
//(異常不是功能本身造成,而是用戶在使用功能的時傳遞參數錯誤而導致功能運行失敗。)
繼承Exception,必須要throws聲明,一聲明就告知調用者進行捕獲,一旦問題處理了調用者的程序會繼續執行。
但是如果使用到了對象的數據,導致都失敗的。
繼承RuntimeExcpetion,不需要throws聲明的,這時調用是不可能編寫捕獲代碼的,因為調用根本就不知道有問題。
一旦發生異常,調用者程序會停掉,並有jvm將信息顯示到屏幕,讓調用者看到問題,修正代碼。在用throws拋出一個的時候,如果這個異常是屬於RuntimeException的體系的時候,我們在調用的地方可以不用處理。(RuntimeException和RuntimeException的子類)
聲明:將問題標識出來,報告給調用者。如果函數內通過throw拋出了編譯時異常,而捕獲,那麽必須通過throws進行聲明,讓調用者去處理。
捕獲:Java中對異常有針對性的語句進行捕獲。
語句:
try
{
//需要被檢測的語句。
}
catch(異常類 變量)//參數。
{
//異常的處理語句。
}
finally
{
//一定會被執行的語句,並且在return之前運行。
}
try catch : 對代碼進行異常檢測,並對檢測的異常傳遞給catch處理。
try finally : 對代碼進行異常檢測,檢測到異常後因為沒有catch,所以一樣會被默認jvm拋出。
異常是沒有捕獲處理的。但是功能所開啟資源需要進行關閉,所以finally。只為關閉資源。
try catch finally:檢測異常,並傳遞給catch處理,並定義資源釋放。
異常在繼承或者實現中的使用細節:
1,子類覆蓋父類方法時,如果父類的方法聲明異常,子類只能聲明父類異常或者該異常的子類,或者不聲明。
2,當父類方法聲明多個異常時,子類覆蓋時只能聲明多個異常的子集。
3,當被覆蓋的方法沒有異常聲明時,子類覆蓋時時無法聲明異常的。
舉例:父類存在這種情況,接口也有這種情況,
問題:接口中沒有聲明異常,而實現的子類覆蓋方法時發生了異常,怎麽辦?
無法進行throws聲明,只能catch的捕獲。問題處理不了catch中繼續throw拋出,
但是只能將異常轉換成RuntimeException子類拋出。
異常轉換
對於可以臨時解決但是無法從根本上解決的異常問題,
需要繼續聲明throws出去,轉換成調用者可以解決的問題。
System.out.println(e.toString());//打印異常的名稱+異常的信息。
System.out.println(e.getMessage());//打印異常信息。
多個異常同時被捕獲的時候,記住一個原則:
先逮小的,再逮大的。
**finally:永遠被執行,除非退出jvm。System.exit(0);
面試題2個。
***:final,finally,finalize區別。
final是最終的意思。它可以用於修飾類,成員變量,成員方法。
它修飾的類不能被繼承,它修飾的變量時常量,它修飾的方法不能被重寫。
finally:是異常處理裏面的關鍵字。
它其中的代碼永遠被執行。特殊情況:在執行它之前jvm退出。System.exit(0);
finalize:是Object類中的一個方法。
它是於垃圾回收器調用的方式。
***:假如catch中有return語句, finally裏中的代碼會執行嗎?
是在return前,還是在return後呢?
會,在return前執行finally裏面的代碼。
throws和throw的區別
A:有throws的時候可以沒有throw。
有throw的時候,如果throw拋的異常是Exception體系,那麽必須有throws在方法上聲明。
B:throws用於方法的聲明上,其後跟的是異常類名,後面可以跟多個異常類,之間用逗號隔開
throw用於方法體中,其後跟的是一個異常對象名
【黑馬程序員濟南校區】java基礎:異常