前言
今天在review代码的时候,发现一个星期前遗留在代码块内的魔法值还未被删除!在侥幸没被拉出去挨三十大板的同时也写一篇文章吧,希望看过的同学们不要犯这样的错误啦。
魔法值是什么?
所谓魔法值,是指在代码中直接出现的数值,只有在这个数值记述的那部分代码中才能明确了解其含义。
在我们刚开始接触高级编程语言时,经常会写这样的代码。
int [] a = new int[4];
for (int i = 0; i < 10; i++) {
if(a[2] >= 4)
doSomething();
}
如果别人看到了你的代码,他们可能会想,为什么数组长度为4?为什么要将循环控制在10次?为什么当数组第三个元素大于等于4时,才执行函数?阅读代码的人只能跟进doSomething方法体内想办法通过代码来回答自己的问题,或者直接解决写这个代码的人,无疑加大了别人的代码阅读量和劳动力。而且如果当你时隔多年回过头来看自己写过的代码,也许你也会不知所措。
在阿里Java编程规范中关于常量定义的第一点就提到了魔法值。
- 【强制】不允许任何魔法值(即未经预先定义的常量)直接出现在代码中。
反例:String key = “Id#taobao_” + tradeId;
cache.put(key, value);
// 缓存 get 时,由于在代码复制时,漏掉下划线,导致缓存击穿而出现问题
解决办法
将所有的魔法值用常量来定义,并且在常量命名上一定要清晰明确。
static final int LENGTH_OF_REVENUE = 4;
static final int TEN_YEARS = 10;
static final int THIRD_PART = 2;
static final int MINIMUN_EXPECTATION = 4;
int [] revenue = new int[LENGTH_OF_REVENUE];
for(int i = 0;i < TEN_YEARS; i++) {
if(revenue[THIRD_PART] >= MIN)
doSomething();
}
经过常量定义了之后,我们就知道这个初学者是想通过doSomething()函数模拟10年以内每年第三季度的收入变化。是不是就比之前更清晰直观了(当然实际情况也不会写这样的代码,此处仅为举例)。
关于常量命名,也可以参考阿里的Java编程规范
- 【强制】常量命名全部大写,单词间用下划线隔开,力求语义表达完整清楚,不要嫌名字
长。
正例:MAX_STOCK_COUNT / CACHE_EXPIRED_TIME
反例:MAX_COUNT / EXPIRED_TIME