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
对象(而不是primitiveint
),以节省内存。因此,添加它是出于性能原因,而不是为了代码清晰。现在它已经过时了:即使您需要一个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。@CKingINTEGER\u ONE
是什么意思?在世界崩溃之前,你能猜到你的登录信息多少次?还是更简单的事情?这正是问题的关键:INTEGER_ONE没有比Literal 1更重要的意义,因此,就代码的清晰性和可维护性而言,它没有任何优势。那么,整个问题就无关紧要了,他的问题将是变量命名约定比幻数更糟糕。我只是给了他一个怀疑的机会,并假设他可怜的变量名是一个“错误”