java異常處理方式推薦做法_談談Java異常處理這件事兒

此文已由作者謝蕾授權網易云社區發布。

歡迎訪問網易云社區,了解更多網易技術產品運營經驗。

前言

我們對于“異常處理”這個詞并不陌生,眾多框架和庫在異常處理方面都提供了便利,但是對于何種處理才是最佳實踐,也是眾說紛紜。異常處理是否得當直接關系到軟件的健壯性,今天就談談我對異常處理這件事兒的拙見。首先,先說一下異常處理的通俗解釋:當危險或知道事情不對的時候做出的反饋。

目錄結構Java的異常分類

常見的異常處理的方法

推薦的實踐方式

1. Java的異常分類

先簡單用圖介紹一下Java的異常分類:

a67aba46c3365f086180adb61abaabc1.png

JAVA這種面向對象的語言,同樣把異常當作對象來處理,Throwable作為所有異常的超類,然后定義了許多異常類,將這些異常類分為兩大類:錯誤Error和異常Exception。其中,Exception異常類又分為RuntimeException和Checked Exception(也叫非運行時異常)。 Error是程序無法處理的錯誤,比如OutofMemoryError、TheadDeath等。Exception是程序本身可以處理的異常,應當盡可能去處理這些異常。運行時異常都是RuntimeException類及其子類異常,這些異常是不檢查異常,程序中可以選擇捕獲處理,也可以不處理,如NullPointerException。通常,這些異常一般是由錯誤代碼邏輯引起的,我們應該從邏輯角度盡可能避免這類異常的發生。 非運行時異常從程序語法角度講是必須進行處理的異常,如果不處理,程序就不能編譯通過。如IOException 、SQLException等以及用戶自定義的異常,一般情況下不自定義運行時異常。

2. 常見的異常處理方法

根據Java工程分層的思想,異常處理也是基于分層的思想。每層都和他的上下層之間都有一個契約,契約內容中就包含了異常處理。任何一層都可能遇到不測,如果遇到了未知的錯誤,不知道如何處理時,通常的做法就是愉快的向上層拋出一個異常,渴求有一層能正確處理掉這個可憐的錯誤。我們常用的Java異常處理機制通常依賴于try、catch、finally、throw、throws。?常見的異常處理方式如下:吞掉并拋出

打印log并拋出

嵌套處理并拋出

忽略異常

2.1 吞掉并拋出try{

...

}catch(Exception?e){throw?new?ApiException(ApiErrorCode.SqlErr,?"Failed?to?get?JobID.");

}

注:ApiException是程序自定義的異常,與SQLEXCEPTION、RUNTIMEEXCEPTION等都屬于異常的一種。 比較明顯,這種處理方式導致丟失了真實的錯誤信息,不利于上層做出正確的處理。非常不好的實踐。

2.2 打印log并拋出try{

boolean?ret?=?sendNotify(info);

if(ret){

i.remove();

}

}catch(ParseException?|?IOException?e){

logger.error("unexpected?exception?happened?while?send?notify?to?client!?remove?notify?message!?jobID:?"?+?info.getJobID(),?e);

throw?e;

}

這個做法想必大家經常看到,在許多工程中都用了這樣的做法。但是這樣的處理方式也在一定環境下也有問題,比如,當異常發生在調用層次較深的底層時,同樣的錯誤信息處理方式,會導致我們為了定位問題將看到無數的相同錯誤信息。所以,具體的異常處理方法還需要綜合上下文來處理。

2.3 嵌套處理并拋出try{

...

}catch(SQLException?e){throw?new?XxxException("Error?in?Xxx",?e);

}

這段代碼catch住了sql異常,然后將其封裝為另外一種異常拋出,期望遇到知心人能讀懂它的良苦用心。

2.4 忽略異常try{

...

}catch(SQLException?ex){

ex.printStacktrace();

}

經常看到這樣的低級錯誤嗎?是的,開發者無情的忽略了異常,并且只把異常信息輸出到控制臺,然后,程序仍然繼續運行,非常有可能導致更多的異常。

3.推薦的實踐方式

此節不敢稱為最佳實踐,因為一切都會隨著空間和時間的變化而變化。只能說下筆者見過的對異常處理的一些推薦做法。如有不適當的地方,請大家指正。如果不知道如何處理異常,最好在定義方法時throws該異常,可以聲明多個異常。

細化異常,盡可能的指定具體的異常,方便問題定位,盡量不要使用范圍太大的Exception。但是,有時一定要最大范圍捕獲的,比如一些線程不想讓它意外退出,那就必須通過最外層捕獲它了。

避免過大的try塊(對所有可能出現異常的代碼進行try塊的包裝),這樣不利于分析問題產生的原因。

一個try對應多個catch時,catch的異常定義可以由精確到一般。

不要無視捕獲的異常,小心因小失大。捕獲到后要么直接拋出,要么重新拋出新類型的異常。

不要在finally塊中return或throw等終止方法的語句,這樣會導致try或catch塊中的return或throw失效。

鼓勵程序適時的進行自定義異常類(非檢測異常的一種),因為異常的類名往往包含了很多有用信息,我們封裝后的異常類可以更加具體的根據代碼或業務處理區分異常類型,方便查找錯誤。

調試時可以使用printStackTrace()方法,但是發布后要避免使用該方法。

管理好自己和其他層之間的異常處理,契約精神,注意:不要把自己能處理的異常拋給別人。

網易云免費體驗館,0成本體驗20+款云產品!

更多網易技術、產品、運營經驗分享請點擊。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/534463.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/534463.shtml
英文地址,請注明出處:http://en.pswp.cn/news/534463.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

as400和java的區別_文件傳輸協議和AS400

我目前收到以下錯誤:遠程服務器返回錯誤:(501)參數或參數中的語法錯誤 .我已經檢查了服務器并且文件確實存在,如果我打開命令提示符并鍵入以下代碼它可以工作:ftpopen 192.168.1.2cd /Imagesget S12345.jpeg這是正常的&#xff0c…

java中同時兩人提交數據_如何一起發送JSON請求和發布表單數據請求?

所以這是一個應該在POST請求中接受以下參數的API:token (as form data)apiKey (as form data){"notification": {"id": 1,"heading": "some heading","subheading": "some subheading","image&qu…

java 64內存不足_請教一個 Java 內存占用的問題

第 1 條附言 364 天前2020-03-04 01:08:55.525 [HikariPool-1 housekeeper] WARN c.z.hikari.pool.HikariPool - HikariPool-1 - Thread starvation or clock leap detected (housekeeper delta1m5s643ms48?s450ns).2020-03-04 01:09:08.516 [task-11] ERROR o.s.s.s.TaskU…

java 抽象類 final_final/抽象類/interface

lesson Thirteen                          2018-05-10 02:10:43final:最終的,可以修飾類、屬性、方法1.final修飾類:這個類就不能被繼承,如:String類,StringBuffer類,System類1…

java char i=2+#039;2#039;;_P039 二維數組的字符按列存放到字符串中 ★★

所屬年份:2010.9;2011.9;2012.3請編寫函數fun,該函數的功能是:將M行N列的二維數組中的字符數據,按列的順序依次放到一個字符串中。例如,若二維數組中的數據為W W W WS S S SH H H H則字符串中的內容應是:WSHWSHWSHWSH。#include#define M 3#d…

java io中斷_JDK源碼閱讀:InterruptibleChannel 與可中斷 IO

來源:木杉的博客 ,imushan.com/2018/08/01/java/language/JDK源碼閱讀-InterruptibleChannel與可中斷IO/Java傳統IO是不支持中斷的,所以如果代碼在read/write等操作阻塞的話,是無法被中斷的。這就無法和Thead的interrupt模型配合使…

java值棧_Struts2學習筆記-Value Stack(值棧)和OGNL表達式

只是本人的Struts2學習筆記,關于Value Stack(值棧)和OGNL表達式,把我知道的都說出來,希望對大家有用。一,值棧的作用記錄處理當前請求的action的數據。二,小例子有兩個action:Action1和Action2Action1有兩個…

php項目實戰流程_一個完整的php流程管理實例代碼分享

1. 添加新流程頁面:請選擇流程節點:session_start();include("../DBDA.class.php");$db new DBDA();$suser "select * from users";$auser $db->Query($suser);foreach($auser as $v){echo " {$v[2]} ";}?>$att…

php cdata,PHPcdata處理(詳細介紹)_PHP教程

PHPcdata處理(詳細介紹)_PHP教程當時在網上找了一個CDATA的轉換器, 修改之后, 將CDATA標簽給過濾掉。如下代碼如下:// States://// out// // // // // // // // in// ]// ]]//// (Yes, the states a represented by strings.)//$state out;$a s…

PHP 與go 通訊,Golang和php通信

不同語言之間的通信方式有很多種,這里我介紹一種最簡單通信方式,json-rpc。Golang自帶json-rpc包,使用起來十分簡單,示例如下,提供一個簡單echo server。package mainimport ("fmt""net""net…

php 接口日志,PHP 開發 APP 接口--錯誤日志接口

APP 上線以后可能遇到的問題:① APP 強退② 數據加載失敗③ APP 潛在問題錯誤日志需要記錄的內容數據表 error_log 字段:idapp_id:app 類別 iddid:客戶端設備號version_id:版本號version_mini:小版本號erro…

php 空模塊,tp5.1配置空模塊,空方法

config/app.php//默認的空模塊名empty_module>index,controller/Error.php<?php namespace app\index\controller;use Env;use think\Controller;class Error extends Controller {//Db::connect(db_ck)//全局MISS路由 在route.php里面設置找不到控制器默認處理//Route:…

centos7php自啟動,centos7系統下nginx安裝并配置開機自啟動操作

這篇文章主要介紹了centos7系統下nginx安裝并配置開機自啟動操作方法,非常不錯&#xff0c;具有參考借鑒價值&#xff0c;需要的朋友可以參考下這篇文章主要介紹了centos7系統下nginx安裝并配置開機自啟動操作方法,非常不錯&#xff0c;具有參考借鑒價值&#xff0c;需要的朋友…

時鐘php,php+js液晶時鐘

php代碼$size_small5;//液晶寬度$size_big25;//液晶長度$distance10;//間距$color_back"#DDDDDD";$color_dark"#CCCCCC";$color_light"#000000";$number0;?>Timer|www.ibtf.net|www.bitefu.netfunction swapcolor(obj,onoff)//改變顏色{if (…

r和matlab學哪個,初學者求教‘r*’是什么意思啊

該樓層疑似違規已被系統折疊 隱藏此樓查看此樓PLOT(X,Y,S) where S is a character string made from one elementfrom any or all the following 3 columns:b blue . point - solidg green o circle : dottedr red x x-mark -. dashdotc cyan plus -- dashedm magenta * star…

php swoole 心跳,聊聊swoole的心跳

來自&#xff1a;桶哥的一篇關于swoole的心跳的文章&#xff0c;作為Swoole顧問(顧得上就問,是為「顧問」)得推一下這篇文章&#xff0c;最后只留下一配置&#xff0c;其實我也不是太明白原理&#xff0c;我在想如果是局域網里還需要心跳&#xff1f;—————————————…

mysql 查詢 投影,MySql-連接查詢

連接查詢Chloe 友好支持多表連接查詢&#xff0c;一切都可以用 lambda 表達式操作&#xff0c;返回類型可以是自定義類型&#xff0c;也可以是匿名類型。強類型開發&#xff0c;編譯可見錯誤&#xff0c;容錯率高。1.建立連接&#xff1a;var user_city_province context.Quer…

php 遞歸欄目名疊加,thinkPHP實現遞歸循環欄目并按照樹形結構無限極輸出的方法,thinkphp遞歸...

thinkPHP實現遞歸循環欄目并按照樹形結構無限極輸出的方法&#xff0c;thinkphp遞歸本文實例講述了thinkPHP實現遞歸循環欄目并按照樹形結構無限極輸出的方法。分享給大家供大家參考&#xff0c;具體如下&#xff1a;這里使用thinkphp遞歸循環欄目按照樹形結構無限極輸出&#…

php cannot call constructor,安裝ECshop普遍問題的解決方法

安裝時的問題&#xff1a;1.Strict Standards: Non-static method cls_image::gd_version() should not be called statically in /usr/local/httpd2/htdocs/upload/install/includes/lib_installer.php on line 31解決&#xff1a;找到install/includes/lib_installer.php中的…

wind試用版 matlab,免費產品試用 - MATLAB Simulink

請選擇其一AlabamaAlaska美屬薩摩亞APO/FPO AAAPO/FPO AEAPO/FPO APArizonaArkansasCaliforniaCaroline IslandsColoradoConnecticutDelawareDistrict of ColumbiaFlorida格魯吉亞關島HawaiiIdahoIllinoisIndianaIowaKansasKentuckyLouisianaMaineMariana Islands馬紹爾群島Mar…