2011-06-14 61 views
4

在不久的将来,我们可能会通过一条规则强制执行这条规则,即我们的java源代码中不能有任何硬编码的数字。所有硬编码数字必须声明为final变量。最好的实践应该避免魔法数字应该走多远?

即使这在理论上听起来很棒,但在代码中实现起来非常困难/繁琐,尤其是遗留代码。在下面的代码片段中将数字声明为final变量应该真的被认为是“最佳实践”吗?

//creating excel 
cellnum = 0; 

//Declaring variables. 
Object[] result = new Object[2]; 

//adding dash to ssn 
return ssn.substring(1, 3)+"-"+ssn.substring(3, 5)+"-"+ssn.substring(5, 9); 

以上只是一些例子我能想到的,但在这些(及其他),你作为一个开发人员会说够了够了?

我想让这个问题成为一个社区维基,但看不到如何...?

+1

这取决于..... – 2011-06-14 15:55:49

+0

什么呢'final'完成,除了让你看起来某处的代码,如果在那里解析任何东西都需要可插入的正则表达式来实现它的多功能性。 – bestsss 2011-06-14 15:59:05

+0

信徒认为做一个变量final并在其他地方重复使用它会在需要改变某些值时有好处,但是,当声明数组或子字符串ssn时,该理论没有意义_always_将是9位数字 – Omnipresent 2011-06-14 16:01:44

回答

6

当然。字面常量有他们的地方,特别是低常量如012,...

我想没有人会认为

double[] pair = new double[PAIR_COUNT]; 

更有意义比

double[] pair = new double[2]; 

我会说使用最终变量如果

  • ......它增加可读性,
  • ...的价值可能会改变(在多个地方使用),或
  • ...它作为文档

一个相关旁注:与编码标准/惯例一样:严格遵守极少数(如果有的话)规则。

+0

不错。我有同样的意见。它需要被控制,而不是标记每个_number_作为硬编码号码 – Omnipresent 2011-06-14 15:58:48

+0

并且还检查0长度字符串等。等等。 – Mikaveli 2011-06-14 16:00:23

+0

右:-)'if(index <0 || index> arr.length)throw .. 。'vs'if(index arr.length)throw ...'例如。 – aioobe 2011-06-14 16:09:21

1

一般来说,如果一个文字具有特殊的含义,它应该被赋予一个唯一的名称而不是假设的东西。我不确定为什么这样做“实际上”很难/乏味。

Object[] result = new Object[2]; =>似乎是一个很好的候选为使用一对类

cellnum = 0; => cellnum = FIRST_COLUMN;特别是你可能最终会使用一个将1作为起始索引的API,或者你想要处理一个从2开始的excel。

return ssn.substring(1, 3)+"-"+ssn.substring(3, 5)+"-"+ssn.substring(5, 9) =>如果你的代码遍布整个代码库,有更大的问题。如果这个代码存在于一个单独的位置,并且被一个理智的API屏蔽,我在这里并没有真正看到问题。

1

我见过人认为0和1接受例外。

这个想法是,你想记录为什么你有两个对象如上例如。 我同意你关于SSN中的破折号。评论比4个命名常量更好地描述它。

一般来说,我喜欢没有幻数的想法,但正如每一条规则一样,有涉及到的语用学。遗留代码带来了自己的问题。就改变行为而言,如果以这种方式更新旧代码,那么很多工作都没有很高的生产力。我会考虑以演化的方式来做这件事:当你必须编辑一个旧文件时,把它提到最新。

0

取决于是否需要更改。或者就此而言,它可以改变。

如果你只需要2个对象(比如,一对像提到aioobe),那么这不是一个号,这是正确的。如果它是一个变量元组,那么在这个时候,它是2,那么你可能应该把它抽象成一个常量。

1

这真的取决于上下文吗?如果代码中有数字不能说明它们存在的原因,那么命名它们会使代码更具可读性。如果你看到编号为3.14的数字是PI吗?有什么方法可以说明或者只是巧合吗?命名它PI将清除这个谜。

在你的例子中,为什么cellnum = 2?为什么不是10?或20?应该命名为INITIAL_CELL或MAX_CELL。特别是如果这个相同的数字,意味着代码中再次出现同样的事情。

4

通过常数替换数字是有意义的,如果数字带有的含义不是固有的,通过单独查看其值。

例如,

productType = 221; // BAD: the number needs to be looked up somewhere to understand its meaning 
productType = PRODUCT_TYPE_CONSUMABLE; // GOOD: the constant is self-describing 

在另一方面,

int initialCount = 0; // GOOD: in this context zero really means zero 
int initialCount = ZERO; // BAD: the number value is clear, and there's no need to add a self-referencing constant name if there's no other meaning