病态使用常数

Mic*_*ele 63 java constants

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

import static org.apache.commons.lang.math.NumberUtils.INTEGER_ONE;
if (myIntVariable == INTEGER_ONE) { ... }
Run Code Online (Sandbox Code Playgroud)

代替:

if (myIntVariable == 1) { ... }
Run Code Online (Sandbox Code Playgroud)

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

Tag*_*eev 84

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

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

  • 但是你不应该在整数对象中使用`==`. (19认同)
  • @Captain Man:没有理由说清楚一个数字是一个好的代码中的数字,所有的文字数字都是一个数字,因为所有其他数字都是由命名常量表示的. (4认同)
  • @ Jean-FrançoisSavard,这是因为这个库保留了Java 1.4的兼容性,它没有`valueOf`方法. (3认同)

See*_*ose 56

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

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

所以通常应该做的是将这些神奇的数字变成常量,其名称代表或解释该数字的含义.常数INTEGER_ONE不解释其含义.

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

static final int MAX_NUMBER_OF_THREADS = 1;
Run Code Online (Sandbox Code Playgroud)

根据Tagir的评论编辑

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

double invert(double x) {
    return 1/x;
}
Run Code Online (Sandbox Code Playgroud)

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

  • @Tagir Valeev:`1/x`中`1`常量的正确名称是`IDENTITY_ELEMENT_WITH_RESPECT_TO_THE_DIVISION_BINARY_OPERATION`.不要感到惊讶,我也更喜欢使用文字"1"... (8认同)
  • 这样的方法怎么样:`double invert(double x){return 1/x;}`?我也应该在这里避免使用"1"吗?如何命名常数呢? (7认同)
  • 实际上,在我知道的许多编码标准中,0和1由于充分的理由而免于No-Magic_Number规则,因为它通常不代表将来可能改变的数字,但是例如某些事物的存在与否(类似的)到一个博尔) (2认同)

Jam*_*ter 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;
Run Code Online (Sandbox Code Playgroud)

用法不好

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?
Run Code Online (Sandbox Code Playgroud)


Ank*_*gam 5

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

因此,在上面的场景中它可能看起来不合适,但如果你在比较时使用它,肯定会产生影响.

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

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

  • 我同意你的答案的第一部分,但你给出使用常量的两个一般原因并不适用于此. (4认同)
  • 然后我建议你重新改写那一部分.在那一刻你要说:*总是喜欢常数*,在你不应该喜欢那个常数的问题的上下文中. (3认同)