Java 常数的病态使用

Java 常数的病态使用,java,constants,Java,Constants,我为什么要写(正如我的同事所说): 而不是: if (myIntVariable == 1) { ... } ? 我知道建议使用常量,但我认为numberrutils.INTEGER\u ONE的值永远不会改变!所以我写了1你可能知道它是否永远不会改变,但如果我开始编辑你的代码,我不会改变 基本上,这是一种在实际代码中记录代码的方法。使用这样的常量和示例的原因是为了避免 也就是说,你可以使用它到一个不再有利和混乱的地步。我倾向于为那些不止一次使用过的东西,或者有被我或其他人改变的观念的东西去做

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

而不是:

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


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

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

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


也就是说,你可以使用它到一个不再有利和混乱的地步。我倾向于为那些不止一次使用过的东西,或者有被我或其他人改变的观念的东西去做。。。或者用更简单的术语重要的值。

org.apache.commons.lang.math.NumberUtils.INTEGER\u ONE
它给你一个
最终的静态整数
对象,而不是原语
int
1,由于它是
final static
,因此它充当常量,可以用于比较
Integer
对象,因为它总是返回相同的实例

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

此外,我们应尽可能倾向于使用常量而不是硬编码的原因:

  • 它可以使您的代码易于维护。如果将来发生任何需要更改的情况,您只能在一个地方进行更改
  • 代码看起来更干净,可读性更强

  • 你不应该。
    INTEGER\u ONE
    名称的意义不超过1。但是,如果此值具有其他含义(例如,一年中的月份),则使用常量(如
    日历.narror
    )将使代码更清晰


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

    想象一下您有这个

    if (myIntVariable == 1) { ... }
    
    但是有几千次

    突然之间,我需要一个2

    什么对你来说更容易改变

    编辑:在否决投票之前,我的回答是从不使用幻数的优点的角度出发的,我没有以任何方式(我认为这是可以推断的,来吧,大家)建议更改库常量。

    你不应该写
    整数
    !您也不应该编写
    1
    (请参见下面的异常)

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

    所以通常应该做的是把这些神奇的数字变成常数,这些常数的名字代表或解释了这个数字的含义。常量
    整数\u ONE
    不能解释其含义

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

    static final int MAX_NUMBER_OF_THREADS = 1;
    

    根据Tagir的评论进行编辑

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

    double invert(double x) {
        return 1/x;
    }
    
    在这里,文本
    1
    在数学域内的上下文中具有含义。因此,它可以按原样使用。

    从中,您将看到它的定义为:

    /** Reusable Integer constant for one. */
    public static final Integer INTEGER_ONE = new Integer(1)
    
    你会看到整数1和1不一样。这是一个已经为你构建的对象。因此,如果我们需要一个
    Integer(1)
    实例,而不是创建自己的实例,那么您可以重用库中的实例,从而节省时间和内存


    这实际上取决于您的应用程序,如果您确实知道1的
    int
    版本是什么,那么您最好使用它而不是这个
    Integer
    类。

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

    不要使用硬编码的“神奇”值。如果某个值是常量,则将其定义为常量。 在某些情况下,可以使用-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?
    
    static NSString*const DatabaseName=@“database.name”;
    //“2”的可接受用法
    浮动x=(屏幕宽度/2)-(图像宽度/2);
    //0的可接受使用
    对于(int i=0;i
    使用不当

    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?
    
    float x=(480/2)-(120/2)//我们得猜这些是尺寸?
    //不必要的常数。
    对于(int i=0;i
    我不同意幻数参数
    INTEGER\u ONE
    总是为1。@CKing
    INTEGER\u ONE
    是什么意思?在世界崩溃之前,你能猜到你的登录信息多少次?还是更简单的事情?这正是问题的关键:INTEGER_ONE没有比Literal 1更重要的意义,因此,就代码的清晰性和可维护性而言,它没有任何优势。那么,整个问题就无关紧要了,他的问题将是变量命名约定比幻数更糟糕。我只是给了他一个怀疑的机会,并假设他可怜的变量名是一个“错误”