常数的病态使用

2022-08-31 15:05:46

我为什么要写(正如我的同事所说):

import static org.apache.commons.lang.math.NumberUtils.INTEGER_ONE;
if (myIntVariable == INTEGER_ONE) { ... }

而不是:

if (myIntVariable == 1) { ... }

?

我知道建议使用常量,但我认为的值永远不会改变!所以我写.NumberUtils.INTEGER_ONE1


答案 1

你不应该。该名称不比 1 更有意义。但是,如果此值具有其他含义(例如,一年中的月份),则使用常量(如 )将使代码更清晰。INTEGER_ONECalendar.FEBRUARY

我可以猜测Commons Math库中的这个常量是在Java 1.4中创建的,当时没有整数缓存和自动装箱,所以它有意义,你可以在不同的地方重用相同的对象(不是原始对象)来节省内存。因此,添加它是出于性能原因,而不是为了代码清晰。现在它已经过时了:即使你需要一个对象,你也可以使用或隐式自动装箱并获取缓存的对象。IntegerintIntegerInteger.valueOf(1)


答案 2

不应该写!你也不应该写(见下面的例外)!INTEGER_ONE1

为什么?文字类似称为幻数。幻数是“具有无法解释的含义或多次出现的唯一值,可以(最好)替换为命名常量”(来自同一维基百科页面的解释)。1

因此,通常应该做的是将这些幻数转换为常量,其名称表示或解释该数字的含义。常量不能解释含义。INTEGER_ONE

因此,您实际上要做的就是在此上下文中找到值的含义,并创建一个具有该名称的常量。例如,如果 表示允许的最大线程数,则应具有如下所示的常量:1

static final int MAX_NUMBER_OF_THREADS = 1;

根据Tagir的评论编辑

如果文本本身在为其编写代码的域中具有含义,则不应将其替换为命名常量。Tagir计算逆元素的例子很好:

double invert(double x) {
    return 1/x;
}

在这里,文字在数学域内的这种上下文中具有意义。因此,它可以按原样使用。1


推荐