Java中的魔法值解決
Java中的魔法值
背景
使用IDEA時(shí),啟用了阿里的代碼規(guī)范檢查,其中就有一項(xiàng)提示是不允許任何魔法值出現(xiàn)在代碼里,于是出于好奇就了解一下到底啥時(shí)魔法值。
介紹
魔法數(shù)值、魔法數(shù)字、魔法值,這是一個(gè)東西,不同的叫法。
魔法數(shù)字,在編程領(lǐng)域指的是莫名其妙出現(xiàn)的數(shù)字。數(shù)字的意義必須通過詳細(xì)閱讀才能推斷出來
if("1".equals(dangerKey)){ ?? ??? ??? ?BigDecimal warningValue = new BigDecimal(JedisUtils.get(WARNING_VALUE_KEY)); ?? ??? ??? ?model.addAttribute("isDanger", true); ?? ??? ??? ?model.addAttribute("warningValue", warningValue); ?? ??? ?}
上面代碼中的字符串1就是一個(gè)魔法值,在未讀整段代碼之前,我并不知道這個(gè)字符串1代表什么意思,只有把這個(gè)字符串帶入后面的代碼邏輯才能判斷該值的真實(shí)意義,而且如果多次出現(xiàn),這就大大的降低了代碼的可閱讀性。所以我們?cè)诖a中應(yīng)該極力避免產(chǎn)生魔法值。
解決方法
** 使用枚舉類型或者使用static final修飾常量 **
//預(yù)警值標(biāo)識(shí) ?? ?public static final String DANGERKEY_TRUE ="1"; ?? ?if(DANGERKEY_TRUE.equals(dangerKey)){ ?? ??? ??? ?BigDecimal warningValue = new BigDecimal(JedisUtils.get(WARNING_VALUE_KEY)); ?? ??? ??? ?model.addAttribute("isDanger", true); ?? ??? ??? ?model.addAttribute("warningValue", warningValue); ?? ??? ?}
以上就是使用static final的方式替換的魔法值,這樣就可以避免了。如果在代碼中多次使用的話,只需更聲明的地方就可以達(dá)到全局的效果。
提示:靜態(tài)常量的命名最好全是大寫字母,如果是多個(gè)單詞需要分割,可以使用下劃線分割。
小結(jié):魔法值的問題對(duì)于代碼邏輯來說,并不是什么要命的事情,即使不修改也基本不影響代碼的正常運(yùn)行,我以前沒有安裝阿里代碼檢查規(guī)范時(shí),一樣這么使用,也沒出現(xiàn)過啥問題。好吧,應(yīng)該說但是了。但是,遵循公認(rèn)的代碼規(guī)范,可以有效的避免開發(fā)過程的一些小問題(最讓人頭疼的往往都是一些小問題引起的),提升開發(fā)的效率和代碼的可閱讀性,老老實(shí)實(shí)按照規(guī)范來,自然就會(huì)受益良多,繼續(xù)加油!
Java的魔法值概念
想象一下,當(dāng)你入職一家新公司,打開工具看以前同事的項(xiàng)目時(shí),突然看到下面這段代碼
String[] catNames = new String[7]; String[] dogNames = new String[7]; for(int i = 0; i < 7; i++) { ?? ?//此處省略若干行 }
你心中一定很凌亂,可能還會(huì)在心底默默問候下寫這段代碼的前同事。
在沒有注釋的情況下,此處的i < 7,你根本無法知道是要處理 dogNames數(shù)組還是catNames數(shù)組,你還要繼續(xù)去看循環(huán)體中的內(nèi)容才能來推斷這個(gè)數(shù)字的含義。這里的7就是魔法值。
所謂的魔法值,就是指在代碼中直接出現(xiàn)的數(shù)值,只有在這個(gè)數(shù)值記述的那部分代碼中才能明確了解其含義。
魔法值簡(jiǎn)單好用,任何項(xiàng)目基本上都會(huì)有魔法值的出現(xiàn)。但魔法值就像一段沒有注釋的代碼,它的出現(xiàn)使得程序的可讀性大大下降,甚至只有當(dāng)事人才知道。這對(duì)于項(xiàng)目或者別的開發(fā)來說,無疑都是不利的。同時(shí),如果到處用到魔法值,那需要修改的時(shí)候,就要修改很多地方,這不僅耗費(fèi)時(shí)間,還很容易會(huì)遺漏。
魔法值的問題就是含義不明且無法統(tǒng)一使用,要把它們統(tǒng)一表示,并加上注釋,我們可以用static final 定義常量或使用enum值。
static final int CAT_NUM = 7; String[] catNames = new String[CAT_NUM]; for(int i = 0; i < CAT_NUM; i++) { ?? ?//此處省略若干行 } for(int i = 0; i < PET.DOG.getNum(); i++) { ?? ?//此處省略若干行 }?
當(dāng)然此處用catNames.length,dogNames.length也不會(huì)引起混淆。
其實(shí)魔法值也并不是要完全禁止不用,畢竟每次用到數(shù)值就要去定義常量或者在enum中新增元素還是很麻煩的。只要保障你的數(shù)值不會(huì)讓別人難以閱讀,你就可以使用魔法值。一般 -1、0 和 1不被視為魔法值。
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
使用ShardingSphere-Proxy實(shí)現(xiàn)分表分庫
這篇文章介紹了使用ShardingSphere-Proxy實(shí)現(xiàn)分表分庫的方法,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-02-02spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用
這篇文章主要給大家介紹了關(guān)于spring源碼學(xué)習(xí)之bean的初始化以及循環(huán)引用的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10mybatis攔截器注冊(cè)初始化編寫示例及如何生效詳解
這篇文章主要為大家介紹了mybatis攔截器注冊(cè)初始化編寫示例及如何生效詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08SpringBoot實(shí)現(xiàn)EMQ設(shè)備的上下線告警
EMQX?的上下線系統(tǒng)消息通知功能在客戶端連接成功或者客戶端斷開連接,需要實(shí)現(xiàn)設(shè)備的上下線狀態(tài)監(jiān)控,所以本文給大家介紹了如何通過SpringBoot實(shí)現(xiàn)EMQ設(shè)備的上下線告警,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-10-10Maven的國(guó)內(nèi)鏡像(快速解決jar下載過慢的問題)
下面小編就為大家?guī)硪黄狹aven的國(guó)內(nèi)鏡像(快速解決jar下載過慢的問題)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-06-06