忽略已检查的异常,所有出色的开发人员都在这样做–基于600,000个Java项目
Github和Sourceforge上超過(guò)600,000個(gè)Java項(xiàng)目中的異常處理概述
Java是使用檢查異常的少數(shù)語(yǔ)言之一。 它們?cè)诰幾g時(shí)強(qiáng)制執(zhí)行,并且需要某種處理。 但是……實(shí)踐中會(huì)發(fā)生什么? 大多數(shù)開(kāi)發(fā)人員實(shí)際上處理任何事情嗎? 以及他們?nèi)绾巫龅降?#xff1f;
在本文中,我們將介紹滑鐵盧大學(xué)最近的一項(xiàng)研究數(shù)據(jù),該數(shù)據(jù)涵蓋了來(lái)自GitHub和sourceforge的600,000多個(gè)Java項(xiàng)目中的異常使用。 讓我們深入探討并回答一些問(wèn)題。
catch子句中的十大異常類(lèi)型
嗯,聽(tīng)起來(lái)很熟悉? 最近,我們根據(jù)生產(chǎn)中1,000多個(gè)應(yīng)用程序中的數(shù)據(jù)進(jìn)行了數(shù)據(jù)緊縮后發(fā)布了結(jié)果 ,在其中我們檢查了拋出的前10種異常類(lèi)型。
在這種數(shù)據(jù)緊縮的情況下,研究人員分析了Github和Sourceforge上的Java項(xiàng)目,調(diào)查了catch子句并報(bào)告了發(fā)現(xiàn)的結(jié)果。 讓我們看一下數(shù)據(jù)集的樣子:
catch子句中排名前十的異常類(lèi)型,來(lái)源:“ Java異常處理模式分析”
好吧,我們這里有什么? 研究發(fā)現(xiàn),在Java項(xiàng)目中,檢查異常占未檢查異常數(shù)量的幾乎三倍。 不能在這里打亂編譯器。 在生產(chǎn)數(shù)據(jù)緊縮中 ,我們看到了相反的結(jié)果,其中未檢查最高例外。
這里要注意的一個(gè)重要區(qū)別是,生產(chǎn)緊縮考慮了拋出類(lèi)型,而本研究所指的是捕獲類(lèi)型,它可能與拋出對(duì)象不同/更高級(jí)別。
另一個(gè)見(jiàn)解是,開(kāi)發(fā)人員經(jīng)常使用Throwable和Exception類(lèi)在頂級(jí)捕獲已檢查的異常。 情節(jié)變濃了 。
為了了解有關(guān)如何處理已檢查的異常的更多信息,研究人員檢查了Exception和Throwable處理程序。 捕獲Exception的方法的78%沒(méi)有捕獲其任何子類(lèi),與Throwable的84%相同。 毫無(wú)意義的catch子句。
接下來(lái),讓我們找出這些catch子句中發(fā)生的事情。 也許有希望。
“大多數(shù)程序員會(huì)忽略檢查的異常,而不會(huì)引起注意”
聽(tīng)起來(lái)不好嗎? 繼續(xù)閱讀。 這是研究的真實(shí),真實(shí),正式內(nèi)容。 我們中的許多人對(duì)被檢查的異常有一種刺痛的蜘蛛般的感覺(jué),但是在軟件開(kāi)發(fā)中,很少有數(shù)據(jù)可以為圍繞實(shí)際代碼樣式的問(wèn)題提供冷硬證明。 除了個(gè)人經(jīng)歷和定性研究而不是定量研究。
下表顯示了在前3個(gè)檢查的異常捕獲塊中執(zhí)行的前幾個(gè)操作:
選中的異常捕獲子句中的頂級(jí)操作,來(lái)源:“ Java異常處理模式分析”
我們看到日志語(yǔ)句和e.printStackTrace()在頂部,使它們成為檢查異常捕獲塊中使用的頂部操作,這有助于調(diào)試情況并了解發(fā)生了什么。
臭名昭著的空漁獲量吸引了他們。 Joshua Bloch在“ Effective Java”中描述了理想的情況:“為了捕獲故障,異常的詳細(xì)信息應(yīng)包含促成異常的所有參數(shù)和字段的值”。 空的捕獲塊無(wú)法達(dá)到這個(gè)目的。
另一個(gè)常見(jiàn)用例是引發(fā)未檢查的異常,該異常將替換已檢查的異常。
Mario Fusco在他的Twitter提要上總結(jié)得很好:
Java開(kāi)發(fā)人員在受檢查的異常捕獲塊中所做的事情表明,如果您強(qiáng)迫開(kāi)發(fā)人員執(zhí)行不必要的smtg,則他將使smtg變得愚蠢
— Mario Fusco(@mariofusco) 2016年6月6日
但是等等,還有更多
從檢查異常和未檢查異常的整體情況來(lái)看,這一次僅在Github上,我們看到類(lèi)似的情況,而重新引發(fā)獲得了更多的歡迎:
異常處理(Github)中使用的頂級(jí)操作,來(lái)源:“ Java異常處理模式分析”
總計(jì)(6,172,462)個(gè)捕獲塊中有20%為空。 這是很糟糕的。 將點(diǎn)與以下事實(shí)聯(lián)系起來(lái):在層次結(jié)構(gòu)中,較高級(jí)別的異常比特定類(lèi)型使用的頻率更高,研究人員得出的結(jié)論是:“大多數(shù)參與者似乎將異常處理作為一項(xiàng)任務(wù)給予了較低的優(yōu)先級(jí),或者將異常包括在他們的任務(wù)中。僅在語(yǔ)言強(qiáng)迫他們處理檢查的異常時(shí)才進(jìn)行編碼。”
最終,產(chǎn)品質(zhì)量受損。
重新拋出是怎么回事?
由于在調(diào)用堆棧層次結(jié)構(gòu)中引發(fā)異常是最流行的catch子句操作,因此研究人員進(jìn)一步研究了哪種轉(zhuǎn)換最為流行。 下表中匯總了結(jié)果:
頂級(jí)異常轉(zhuǎn)換,來(lái)源:來(lái)源:“ Java異常處理模式分析”
在#1中,將Exception轉(zhuǎn)換為RuntimeException。 從任何異常類(lèi)型進(jìn)行的大多數(shù)轉(zhuǎn)換都轉(zhuǎn)換為RuntimeException,從而使未檢查的異常變?yōu)檫x中狀態(tài)。
例外最佳做法
除了數(shù)據(jù)緊縮及其洞察力之外,本文還提到了約書(shū)亞·布洛赫(Joshua Bloch)處理其著名的第二版書(shū)“有效Java”中的異常的準(zhǔn)則(第9章)。 我們認(rèn)為在此處列出它們也是一個(gè)好主意:
1.“僅在例外情況下使用例外”
異常在JVM上造成相當(dāng)大的開(kāi)銷(xiāo),將異常用于常規(guī)流控制會(huì)帶來(lái)麻煩(是的,即使許多開(kāi)發(fā)人員濫用了它)。 在可執(zhí)行的例外情況文章中 ,我們?cè)敿?xì)介紹了這個(gè)“常規(guī)例外情況”問(wèn)題。
2.“將可檢查的異常用于可恢復(fù)的條件,將運(yùn)行時(shí)異常用于編程錯(cuò)誤”
這意味著,如果開(kāi)發(fā)人員發(fā)現(xiàn)檢查后的異常不可恢復(fù),則可以將其狀態(tài)包裝在未經(jīng)檢查的異常中,然后將其拋出層次結(jié)構(gòu)以進(jìn)行日志記錄和處理。
3.“避免不必要地使用檢查的異常”
僅在無(wú)法通過(guò)正確編碼API避免異常且沒(méi)有其他恢復(fù)步驟時(shí),才使用檢查的異常。
4.“善用標(biāo)準(zhǔn)例外”
使用已經(jīng)廣泛的Java API中的標(biāo)準(zhǔn)異常可提高可讀性。
5.“拋出適合抽象的異常”
在層次結(jié)構(gòu)中前進(jìn)時(shí),請(qǐng)使用適當(dāng)?shù)漠惓n?lèi)型。
6.“記錄每種方法引發(fā)的所有異常”
當(dāng)涉及異常時(shí),沒(méi)有人會(huì)喜歡驚訝。
7.“在詳細(xì)消息中包含故障捕獲信息”
沒(méi)有有關(guān)JVM所處狀態(tài)的信息,您無(wú)法做很多事情來(lái)確保不會(huì)再次發(fā)生該異常。 并不是每個(gè)人都有Takipi掩蓋他們的背部。
8.“不要忽略例外”
所有異常都應(yīng)導(dǎo)致采取某些措施,您還需要它們做什么?
要了解有關(guān)這些準(zhǔn)則的更多信息,請(qǐng)查看上一篇有關(guān)可操作異常的博客文章 ,以及最近一次涵蓋1000多個(gè)生產(chǎn)應(yīng)用程序的生產(chǎn)數(shù)據(jù)緊縮的教訓(xùn),以了解其日志中的內(nèi)容以及遇到的十大異常 。
我們到底在看什么呢?
這項(xiàng)研究的數(shù)據(jù)來(lái)自加拿大安大略省滑鐵盧大學(xué)的David R. Cheriton計(jì)算機(jī)科學(xué)學(xué)院的Suman Nakshatri , Maithri Hegde和Sahithi Thandra的研究論文 。
研究人員研究了780萬(wàn)個(gè)Github項(xiàng)目和70萬(wàn)個(gè)Sourceforge項(xiàng)目的數(shù)據(jù)庫(kù) ,提取了Java項(xiàng)目,并檢查了BOA領(lǐng)域特定語(yǔ)言對(duì)catch塊在挖掘軟件存儲(chǔ)庫(kù)中的使用情況。
數(shù)據(jù)集由數(shù)字
最后的想法
例外情況應(yīng)保留例外情況,但是……其他情況在實(shí)踐中會(huì)發(fā)生。 被檢查的異常變得不受檢查,到處都是空的catch塊,控制流與錯(cuò)誤流混合在一起,有很多噪音,關(guān)鍵數(shù)據(jù)丟失了。 一團(tuán)糟。
這是我們構(gòu)建Takipi的主要?jiǎng)訖C(jī), Takipi是一個(gè)Java代理,用于監(jiān)視生產(chǎn)中的JVM,并負(fù)責(zé)使用您需要了解異常行為(以及如何避免異常)的所有信息來(lái)填補(bǔ)空白。
翻譯自: https://www.javacodegeeks.com/2016/06/ignore-checked-exceptions-cool-devs-based-600000-java-projects.html
總結(jié)
以上是生活随笔為你收集整理的忽略已检查的异常,所有出色的开发人员都在这样做–基于600,000个Java项目的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一个好的移动广告平台是广告主盈利的关键
- 下一篇: js实现京东秒杀