日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

做好异常处理,防止无故翻车

發布時間:2023/12/8 编程问答 61 豆豆
生活随笔 收集整理的這篇文章主要介紹了 做好异常处理,防止无故翻车 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

絮叨

因為程序異常處理問題,就在前幾天龍叔的服務掛了幾秒鐘。

完了,馬上季度末打績效,竟然在這里翻車了,心如刀絞啊。

雖然沒有影響到用戶體驗,但是找到問題并解決掉問題是工程師日常追求之一。

作為一個優秀的工程師,應該還得加幾點:

  • 弄清問題本質
  • 總結問題原因
  • 舉一反三,防止出現類似錯誤

異常處理,對于每個開發者來說一點不陌生。

有人這樣描述,“一個開發者90%的時間都是在處理程序異常”。

這樣說也不算是什么過錯,畢竟正常的邏輯總是輕松容易的寫完,異常處理往往會占據開發者大多數時間。

既然這么占據我們的開發時間,何不主動花點時間去了解他熟悉他,切莫讓他成為了最熟悉的陌生人。

文章大綱

異常分類

在Java中,異常分為受檢查的異常,與運行時異常。兩者都在異常類層次結構中。下面的圖展示了Java異常類的繼承關系。

不難看出所有的異常都繼承自一個共同的父類Throwable,而Throwable有兩個重要的子類:Exception(異常)和Error(錯誤)。

Error(錯誤)

工程師最怕的就是Error,看到error和fail頭都大了三圈,感覺Error總是和我過不去。

Error是指Java 運行時系統的內部錯誤和資源耗盡錯誤。

應用程序不應該拋出這種類型的對象。

如果出現了這樣的內部錯誤, 除了通告給用戶,并盡力使程序安全地終止之外, 再也無能為力了。一般這種情況很少出現。

這種錯誤會導致你的程序日常運行著,突然某天就夭折了。

Exception(異常)

異常指不期而至的各種狀況,如:文件找不到、網絡連接失敗、非法參數等。

異常是一個事件,它發生在程序運行期間,干擾了正常的指令流程。

Java通過API中Throwable類的眾多子類描述各種不同的異常。因而,Java異常都是對象,是Throwable子類的實例,描述了出現在一段編碼中的錯誤條件

當條件生成時,錯誤將引發異常。

異常和錯誤的區別:異常能被程序本身處理,錯誤是無法處理。

異常主要分為運行期異常非運行期異常(編譯異常)

運行期異常很好理解,就是程序跑著跑著因為觸發某個條件,導致異常發生了。比如越界了,NullPointerException等等。

編譯期異常,就是程序編譯時拋出的異常,比如訪問的文件不存在。這類異常很好避免,編譯不會通過,不解決掉,程序就沒法運行起來。

當然有人也把異常分為可查異常不可查異常

可查異常 也稱之為編譯器要求必須處理的異常,一般編譯器都會檢查他,出現這類異常要么用捕獲他,要么拋出他,總之必須處理他。

不可查異常 編譯器沒法檢查的,必須靠程序員去主動檢查,然后處理掉他。

分類的方法不是很重要,怎樣分取決于你處于某種情況下,最終都是要明白這些異常,并處理它。

異常處理機制

上面基本都明白了java異常是什么,以及有哪些異常,下面我們就來聊聊用什么樣的機制去處理這些異常。

八字方針 拋出異常,捕捉異常

throw 語句用于拋出異常,throws 語句用于聲明可能會出現的異常。

舉個例子:

public Integer division(int x, int y) {if (y == 0)throw new ArithmeticException("拋出算術異常"); //拋出異常return x / y;}

throws拋出異常的規則:

  • 如果是不可查異常(unchecked exception),即Error、RuntimeException或它們的子類,那么可以不使用throws關鍵字來聲明要拋出的異常,編譯仍能順利通過,但在運行時會被系統拋出。
  • 2)必須聲明方法可拋出的任何可查異常(checked exception)。即如果一個方法可能出現受可查異常,要么用try-catch語句捕獲,要么用throws子句聲明將它拋出,否則會導致編譯錯誤

    3)僅當拋出了異常,該方法的調用者才必須處理或者重新拋出該異常。當方法的調用者無力處理該異常的時候,應該繼續拋出,而不是囫圇吞棗。

    4)調用方法必須遵循任何可查異常的處理和聲明規則。若覆蓋一個方法,則不能聲明與覆蓋方法不同的異常。聲明的任何異常必須是被覆蓋方法所聲明異常的同類或子類。

    java采用try-catch-finally語句來對異常進行捕獲并處理。

    try{//可能產生異常的代碼 }catch (Exception e){//異常處理邏輯 } try{//可能產生異常的代碼 }catch (Exception e){//異常處理邏輯 }finally {//必須執行的邏輯 }

    這語法大家應該在熟悉不過了,算了,龍叔還是啰嗦一遍。

    try語句塊:該語句塊中是程序正常情況下應該要完成的功能,而這些代碼中可能會產生異常,其后面的catch語句塊就是用來捕獲并處理這些異常的。

    catch語句塊:該語句塊用來捕獲并處理try語句塊中產生的異常。

    每個catch語句塊聲明其能處理的一種特定類型的異常,catch后面的括號中就是該特定類型的異常。

    在Java7以前,每個catch語句塊只能捕獲一種異常,從Java7開始就支持一個catch捕獲多種異常,多個異常之間用|隔開。

    try{//可能會產生異常的代碼}catch(Exception1 | Exception2 |... | Exception_n e1){//統一處理的異常代碼}finally{//通常是釋放資源的代碼}

    finally塊:無論是否捕獲或處理異常,finally塊里的語句都會被執行。當在try塊或catch塊中遇到return語句時,finally語句塊將在方法返回之前被執行。

    在以下4種特殊情況下,finally塊不會被執行:

    1)在finally語句塊中發生了異常。
    2)在前面的代碼中用了System.exit()退出程序。
    3)程序所在的線程死亡。
    4)關閉CPU。

    try、catch、finally語句塊的執行順序:

    到這里大家基本明白了異常怎么來的,怎么處理的,接下來說一個常見的異常屏蔽問題

    一般情況下都是try中進行捕捉可能出現的異常,catch對異常進行處理,finally中進行一些資源關閉工作。

    正常情況倒也沒啥說的,但咋就怕異常情況啊。

    舉個例子:

    try{//可能會產生異常的代碼}catch(Exception1 | Exception2 |... | Exception_n e1){//統一處理的異常代碼}finally{//通常是釋放資源的代碼in.close();out.close();}

    是不是日常都這么寫,看起來蠻正常的。

    如果我們的finally語句塊中也拋出異常,會怎么辦?

    public Integer division(int x, int y) throws Exception {try{return x/y;}catch (ArithmeticException e){System.out.println(e.getMessage());throw new ArithmeticException("算術異常");}finally {System.out.println("釋放資源");throw new Exception("釋放資源異常");}}

    例如這段代碼,本意是想拋出算術運算異常 ,結果拋出了釋放資源異常

    由于異常信息的丟失,異常屏蔽可能會導致某些bug變得極其難以發現,會讓你加班加到心態崩潰的。

    這就是屏蔽異常,如何解決這種屏蔽異常?

    有人看了上面的代碼,又發現了另一個問題。try中有return語句,finally語句還會不會執行?

    這個問題很好,答案是會執行,并且在方法返回調用者前執行

    解決屏蔽異常問題

    Java 1.7中新增的try-with-resource語法糖來很好的解決這種因為關閉資源引起的異常屏蔽問題。

    public void testExcep(){BufferedInputStream in = null;BufferedOutputStream out = null;try {in = new BufferedInputStream(new FileInputStream(new File("in.txt")));out = new BufferedOutputStream(new FileOutputStream(new File("out.txt")));} catch (IOException e) {e.printStackTrace();} finally {try {if (in != null) {in.close();}if (out != null) {out.close();}} catch (IOException e) {e.printStackTrace();}}}

    為了釋放資源,我們不得不這樣寫。但當我們熟悉try-with-resource語法,我們可以這樣寫。

    public static void main(String[] args) {try (BufferedInputStream in = new BufferedInputStream(new FileInputStream(new File("in.txt")));BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(new File("out.txt")))) {//處理輸入數據并輸出} catch (IOException e) {//捕捉異常并處理}}

    在try子句中能創建一個資源對象,當程序的執行完try-catch之后,運行環境自動關閉資源。

    代碼寫起來簡潔,也會解決掉屏蔽異常問題

    當然也要注意,在使用try-with-resource的過程中,一定需要了解資源的close方法內部的實現邏輯。否則還是可能會導致資源泄露。

    怎么樣,是不是很簡單呢?學會了我們一起去裝逼

    常見異常問題

    算術異常類:ArithmeticExecption

    空指針異常類:NullPointerException

    類型強制轉換異常:ClassCastException

    數組負下標異常:NegativeArrayException

    數組下標越界異常:ArrayIndexOutOfBoundsException

    文件已結束異常:EOFException

    文件未找到異常:FileNotFoundException

    字符串轉換為數字異常:NumberFormatException

    操作數據庫異常:SQLException

    輸入輸出異常:IOException

    方法未找到異常:NoSuchMethodException

    這些都是非常常見的異常,當然還有一些其他異常,大家要在日常工作中及時總結,寫到你的小本本上。

    今天的內容就到這里了,有幫助記得點個贊👍。

    我是龍叔,我們下期見??。

    總結

    以上是生活随笔為你收集整理的做好异常处理,防止无故翻车的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。