病态使用常数

时间:2015-07-17 08:29:19

标签: java constants

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

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

而不是:

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

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

7 个答案:

答案 0 :(得分:83)

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

我可以猜测Commons Math库中的这个常量是在没有Integer缓存和自动装箱的情况下在Java 1.4中创建的,所以你可以重用相同的Integer对象(不是原始的{{{ 1}})在不同的地方节省内存。所以它是出于性能原因而添加的,而不是代码清晰度。现在已经过时了:即使您需要int对象,也可以使用Integer或隐式自动装箱并获取缓存的对象。

答案 1 :(得分:56)

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

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

所以通常应该做的是将这些神奇的数字用于其名称代表或解释该数字含义的常数。常数INTEGER_ONE没有解释其含义。

所以你真正需要做的是在这个上下文中找到值的含义并创建一个具有该名称的常量。例如,如果1表示允许的最大线程数,则应该有一个常量,如:

static final int MAX_NUMBER_OF_THREADS = 1;

根据Tagir的评论编辑

如果文字本身在您编写代码的域中有意义,那么它不应该被命名常量替换。 Tagir用于计算逆元素的示例是一个很好的例子:

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

这里的文字1在数学域内的这个上下文中有意义。所以它可以按原样使用。

答案 2 :(得分:19)

我恰好为我的公司编写了风格指南,我建议如下:

  

不要使用硬编码的“魔术”值。如果值是常量,请将其定义为。   在某些情况下可以使用-1,0,1,2,100等数字。

我的示例在Objective-C中,因为这是我编写指南的语言,但规则仍然适用。

良好用法

static NSString* const DatabaseName = @"database.name";

//Acceptable use of "2"
float x = (ScreenWidth / 2) - (ImageWidth / 2);

//Acceptable use of 0
for (int i = 0; i < NumberOfItems; i++)

//Acceptable use of 100, but only because the variable is called "percentage"
float percentage = (someObjects * 100) / allObjects.count;

使用不当

float x = (480 / 2) - (120 / 2); //We have to guess these are sizes?

//Unneccessary constants.
for (int i = ZERO; i < NumberOfItems; i += ONE)

float percentage = (someObjects.count * 100) / 120; //What is 120?

答案 3 :(得分:5)

org.apache.commons.lang.math.NumberUtils.INTEGER_ONE它为您提供了一个final static Integer对象而非原始int 1,因为它是final static,它充当一个常量,可以用来比较{ {1}}对象,因为它总是返回相同的实例。

所以在上面的场景中它可能看起来不是 fit 但是如果你在比较时使用它,那肯定会产生影响。

此外,尽可能多地使用常量而不是硬编码:

  1. 它可以使您的代码易于维护。如果将来发生任何变更情况,您只能在一个地方进行更改。
  2. 代码看起来更干净&amp;更具可读性。

答案 4 :(得分:1)

您可能知道它是否永远不会改变,但如果我开始编辑您的代码我就不会...

基本上,这是一种在实际代码中记录代码的方法。使用常量和这样的示例的原因是为了避免Magic Numbers in code and their disadvantages.

话虽如此,你可以将它用于不再有利的地方并且杂乱诱导。我倾向于为不止一次使用过的东西做这件事,或者让我或其他人改变概念......或者用更简单的术语重要的值。

答案 5 :(得分:1)

Class NumberUtils开始,您会看到它被定义为:

/** Reusable Integer constant for one. */
public static final Integer INTEGER_ONE = new Integer(1)

所以,你会看到INTEGER_ONE与1不同。它是一个已经为你构建的对象。因此,如果我们需要Integer(1)的实例,而不是创建自己的实例,则可以重用库中的一个来节省时间和内存。

这实际上取决于你的应用程序,如果你确实是int版本的1,那么你可能更好地使用它而不是这个Integer类。

答案 6 :(得分:-3)

想象一下,你有这个

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

但是几千次......

突然之间需要成为一名2。

您更容易改变什么?

编辑:在关注投票之前,我从不使用魔术数字的优势的角度回答,我不以任何方式(我认为这是可推断的,来到人们)建议改变库常数。