1. 程式人生 > >【黑馬程序員濟南校區】java基礎:異常

【黑馬程序員濟南校區】java基礎:異常

java

Exception:

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基礎:異常