Java:异常的概念及分类、异常的处理、异常抛出及自定义异常
異常概念
異常分類
? Java異常處理機制
try ...catch...finally
throw和throws
自定義異常
一、異常的概念
????????什么是異常?
? ? ? ? ? ? ? ? 所謂異常是指在程序運行的過程中發生的一些不正常事件。(如除0溢出,數組下標越界,所要讀取的文件不存在)。(比如上下轉型的時候,出現類型轉換異常)
? ? ? ? 異常導致的后果?
? ? ? ? ? ? ? ? Java程序的執行過程中如出現異常事件,可以生成一個異常類對象,該異常對象封裝了異常事件的信息,并將其被提交給Java運行時系統,這個過程稱為拋出異常,不處理的話會直接導致程序直接中斷
? ? ? ? 如何讓防止程序中斷???
? ? ? ? ? ? ? ? 設計良好地程序應該在程序異常發生時提供處理這些異常的方法,使得程序不會因為異常的發生而阻斷或產生不可預見的結果
異常的分類
? ? ? ? ? ? ? ? ? ? ? ? ????????????????Throwable?? ? ??
Error? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?????????????????????????????????????? ? ? ? ? ? ?Exception
????????????????????????????????????????????????????????IOException?????????????????????????? ? ? ? Runtime? ?Exception? ? ? ? ? ? ? ? ? ??
????????
| ????????異常類型 | ? ? ? ?????????包括 | ????????????????來源 | ????????????????處理 |
| 受查異常 checkedException | Excption及其子類 (不包括 RuntimeException 及其子類) | 由代碼控制能力之 外的因素導致的運 行時錯誤 | 必須要處理,否則 通不過編譯 |
| 非受查異常 uncheckedException | Error和 RuntimeException 及其子類 | RuntimeException 一般代表編程錯誤 | 可以不用處理 |
這種Error是系統運行Java虛擬機的異常,這種異常跟我們寫的代碼沒有關系,像這種異常我們處理不了,基本上檢查操作系統,檢查運行的環境
我們能處理的異常叫做? ?Exception? ?
? ? ? ? 它分為??IOException? ? ? ? ? 和? ? ? ? ? ?Runtime? ?Exception
??IOException就像我們讀取磁盤的某個文件不存在,怎么辦。v
由代碼控制能力之外的因素導致的運行時錯誤:比如你去讀取磁盤上的某個文件,在運行的過程中消失了,讀取失敗,或者你連接某個服務器,連接某個網絡,連不上了,你不能因為這種異常導致程序崩了呀,這時候必須要處理,否則編譯通不過,編譯通不過是小事,最害怕程序運行一半崩了
非受查異常:可以不用處理
RuntimeException一般代表編程錯誤:代表你程序員寫代碼的水平是有問題的,比如說,除數除以0,或者多態講解的上下轉型,向下轉型的時候,你把狗轉化成了貓,那你之前為什么不做一個instanceof的判斷呢?都是程序員常規的編碼錯誤,這種錯誤處理也沒什么意義
二、Java異常處理機制
? ? ? ? Try-catch-finally
try? ? ?監控區域,執行可能產生異常的代碼
catch? ? ? ? ?捕獲、處理異常
finally? ? ? ? 善后處理,無論是否發生異常,代碼總能執行
try? 監控區域,執行可能產生異常的代碼:
讀文件,連接網絡,它可能出現文件沒有,或連接不上網絡
放在生活中,比如你去上班路上堵車,你不可能因為堵車今天就不去上班了
堵車就是一件異常事件,try就是你嘗試從家里到公司這件事情,catch 就是堵車,finally打電話報備一下今天會遲到
try -catch -finally
? ? ? ? try{}語句塊中放的是要檢測的Java代碼,可能有會拋出異常,也可能會正常執行
? ? ? ? catch{}(異常類型){}塊是當Java運行時系統接收到try塊中所拋出的異常對象時,會尋找能處理這一異常catch塊來進行處理(可以有多個catch塊)。
? ? ? ? finallly{}不管系統有沒有拋出異常都會去執行,一般用來釋放資源。除了在之前執行了System.exit(0)
try{}語句塊中放的是要檢測的Java代碼,,可能有會拋出異常,也可能會正常執行:
對一個空指針進行操作的話,他肯定會報錯,報空指針異常然后結束
? ? ? ? catch{}(異常類型){}塊是當Java運行時系統接收到try塊中所拋出的異常對象時,會尋找能處理這一異常catch塊來進行處理(可以有多個catch塊)。
那如果你用catch{}捕獲異常,程序不會崩,會往下走,他會收到catch{}拋出的異常對象
????????finally{}不管系統有沒有拋出異常都會去執行,一般用來釋放資源。除了在之前執行了System.exit(0):
System.exit(0)程序退出
try -catch -finally:
不是說非要三個一起,就像if? else? ,你只有if? ?,沒有else 也是可以的
try 可以和catch 配合 沒有finally
try也可以和finally配合沒有catch
新建一個工程
?運行結果
程序崩了,并且end并沒有輸出
?那如果我們用try 呢?
單獨一個try是不給的
?try加上一個finally,
?運行結果,你會發現程序崩了歸崩了,但是還是能看到end,
所以finally不管異常有沒有拋出,finally里面的東西都會執行
?當然,你try去嘗試跑這個代碼,一定需要catch某個東西,
比如上面這個異常叫java.lang.NullPointerException,我們要去捕獲這個異常
如何捕獲
?運行結果
捕到了,而且程序并沒有崩
?沒有崩如何驗證呢?
程序會正常的跑下去
?運行結果
這就是程序異常的時候,有解決方案
?其實像數學異常也是一樣的
運行結果
?就想輸入0
出現了java.lang.ArithmeticException? ? ? ? ?數學異常
?同樣的去捕獲數學異常
像這種異常是很low的
可以讓他重新再來一次,看能不能解決這個問題,也就是遇見異常后的解決方案
?運行結果
這就是我們說的try? -catch - finally
當然finally可以不用要
?運行結果,當你輸入9的時候,
他不會抓到這些異常,
所以里面的東西也不會去執行????????catch(java.lang.ArithmeticException e)?? ?{
?? ??? ??? ??????????????????????????????????????????????????? ?????????????????System.out.println("你輸入了0,請重新輸入");
?? ??? ??? ??????????????????????????????????????????????????????????????????? ?b = sc.nextInt();
?? ??? ??? ??????????????????????????????????????????????????????????????????????????? ?c =a/b;
?? ??? ??? ??? ?????????????????????????????????????????????????????????????????System.out.println("c="+c);
?? ??? ??? ?????????????????????????????????????????????????????????????? ?}
這樣程序看起來怪怪的,我們可以把c放到下面? ? ? ? ?第 33行
錯誤提示:The local variable c may not have been initialized?
這里面的c看不到
?我們給c做一個初始化? ? ? ? 第14行
?運行結果
輸入0不行,再輸入6可以了,
當然這個1 是因為四舍五了
?修改一下
?運行結果
?他這邊有個問題,他是個語句塊,你如果把a放到try下面的話? ? ? ? 第20行
錯誤提示:a cannot be resolved to a variable
這邊的a就識別不到了? ? ? ? 第30行
有點像局部變量的意思
所以try-catch 這遍的變量注意,盡量往外面放,放到大家都能看見的位置
?異常有很多,大家不需要記住
你去抓住異常的祖先
比如說Exception
他就直接報錯了 : Unreachable catch block for ArithmeticException. It is already handled by the catch block for Exception
已經被Exception處理了,因為Exception 是捕獲所有的異常
?可以全部放在一起運行,不管你是出現了對空指針訪問異常,還是出現了除法異常,都可以
三、異常拋出及自定義異常
throw 和 throws
? ? ? ? throw用于手動拋出異常。作為程序員可以在任意位置手動拋出異常。
? ? ? ? throws用于在方法上標識要暴露的異常。拋出的異常交由調用者處理。
? ? ? ? 兩者區別
????????????????throw用在方法內,后面跟上要拋出的異常類對象
? ? ? ? ? ? ? ? throws修飾在方法上,告訴調用者此方法可能會拋出異常,后面跟上可能要拋出的異常類名
throws用于在方法上標識要暴露的異常。拋出的異常交由調用者處理。:
也就是你分裝了一個方法,要告訴方法的調用者,使用你這個方法會存在什么異常
新建一個工程
? ? ? ?比如說我現在有一個酒吧class Bar
? ? ? ? 然后做一個構造方法????????public Bar(int age){
?? ??????????????????????????????????????????????????? ?this.age = age;
?? ?????????????????????????????????????????????????}
????????然后再來一個檢查,如果age小于18歲,認定是它一個異常,我們就throw一個new
? ?
?運行結果
15歲進來,程序異常,崩了,end不能執行
?我們為了不讓程序崩,在這面try一下
?運行結果
?修改一下24行
運行結果
?也可以把拋出異常的數據給他體現出來e.printStackTrace();
?運行結果
這就是throw的作用,我們可以手動的在某個地方,拋出這個異常
?我們是不是要知道函數存在哪些異常呀,所以這面做一個提醒
void check()throws IllegalArgumentException? ? ? ? 第9行
這樣我catch就能catch到
Java異常處理機制
????????????????throw? ? ? ?????????????????????????????????????????????????????????? ? ? ? ?throws
????????????????拋出異常? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 聲明異常
? ? ? ? ? ? ? ? ? ?throw? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? throws
? ? ? ? ? ? ? ? 手動拋出異常? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 聲明方法可能要拋出的異常
class Bar{
? ? ? ? public void enter(int age){
? ? ? ? ? ? ? ? if(age<18){
? ? ? ? ? ? ? ? ????????//受查異常(必須捕獲,不捕獲編譯都通不過)和非受查異常
? ? ? ? ? ? ? ? ? ? ? ? throw new IllegaArgumentException("年齡不合格");? ? ?
????????????????????????}else{
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? System.out.println("歡迎光臨")?;? ? ? ?
????????????????????????????????}
????????????????????????}
????????????????}?????????
常見異常
? ? ? ? RuntimeException,????????IOException,? ? ? ? SQLException,
? ? ? ? ClassNotFoundException
自定義異常
????????Java提供的異常體系不可能預見所有希望加以報告的錯誤、
·自定義異常類必須從已有的異常類繼承
?·建立新的異常類型最簡單的方法就是讓編譯器產生默認構造方法
?·對異常來說,最重要的部分就是它的類名
? ·可以為異常類定義一個接受字符串參數的構造方法,字符串參數描述異常信息
????????
? ? ? ? 像這種 IllegalArgumentException用的不是那么順,
???????????我們可以自己定義一個?AgeLessThanEighteenException
這種類定義出來,你不能把他叫成異常類,通常Java這邊的習慣是繼承Exception
class AgeLessThanEighteenException extends Exception? ? ? ? ?第16行
????????
?運行結果
我們自定義一個自己的異常,????????class AgeLessThanEighteenException extends Exception
然后拋出這個異常? ? ? ? ? ? ?? ? ? ? ????????? throw new AgeLessThanEighteenException("年紀太小");? ? ? ? ? ? ? ?然后捕獲這個異常???????????????????????????????catch(AgeLessThanEighteenException e)
你要告訴調用者你會產生這種異常????????void check()throws AgeLessThanEighteenException
像這種異常,我們叫做受查異常,因為它繼承Exception
(受查異常:就是我們不修改的話,編譯都通不過
RuntimeException 比如除于0這件事,或者空指針等等,可以不處理,但是程序會崩)
?這種異常沒有catch的話,編譯是不允許的
編譯都不過
錯誤提示:Unhandled exception type AgeLessThanEighteenException
總結
以上是生活随笔為你收集整理的Java:异常的概念及分类、异常的处理、异常抛出及自定义异常的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java:多态的概念和案例实现
- 下一篇: Java:高级之泛型概念引入,泛型可以设