为什么在Java方法名称中使用数字是错误的?

时间:2011-02-11 01:14:35

标签: java methods standards

前一段时间,我记得被告知不要在Java方法名称中使用数字。最近,我有一位同事问我为什么,为了我的生活,我不记得了。

根据Sun(现在是Oracle)的说法,方法名称的一般命名约定是:

  

方法应该是动词,大小写混合   第一个字母小写,带   每个内部单词的第一个字母   大写。

Code Conventions of Java

这并没有具体说明不能使用数字,但遗漏的是你可以看到它不被建议。

考虑您希望根据特定年份执行某些逻辑的情况(我的同事),例如,2011年生效的新政策,因此您的应用程序必须对信息采取行动并根据信息处理在它的一年。常识可以告诉你,你可以调用这个方法:

boolean isSessionPost2011(int id) {}

在方法名称中使用数字是否可以接受(尽管有标准的措辞)?如果没有,为什么?

编辑“这并没有具体说明不能使用这些数字,尽管有些遗漏,你可以看到它不被建议。”也许我说错了。标准说'方法应该是动词'。我读到这一点,说考虑一个数字不是一个动词,那么方法名称不应该使用数字。

17 个答案:

答案 0 :(得分:34)

标准Java类库中包含带有数字的类和方法,如Graphics2D

答案 1 :(得分:19)

该方法似乎......过于具体。

你不能使用:

boolean isSessionAfter(int id, Date date)

这样,下次在特定日期之后将策略应用于任何内容时,您无需复制粘贴旧方法并更改数字 - 您只需使用其他日期进行调用即可。

答案 2 :(得分:8)

当然,在方法名称中使用数字是可以接受的。但按照你的例子,这就是为什么它通常不赞成。让我们说现在有一个新的政策到2012年。现在,有一个新的政策到2014年。也许2020年!所以,你有四种大致相同的方法。

你想要的不是布尔值,而是基于是否找到策略来做某事或什么都不做的策略。因此,一个方法void processPolicy(Structure yourStructure);这将是一个更好的方法 - 现在你可以屏蔽你根据年份进行查找,并且不必每年都有单独的方法,甚至每年只限制一个政策(可能是政策发生)例如,在两个不同的年份,或仅仅三个月)。

答案 3 :(得分:6)

此主题Java Language Specification似乎fairly specific

  

3.8标识符

     

标识符 Java字母 Java数字的无限长度序列,其中第一个必须是Java字母。< / p>      

...

     

Java字母包括大写和小写ASCII拉丁字母A-Z\u0041-\u005a)和a-z\u0061-\u007a),并且由于历史原因,ASCII下划线( _\u005f)和美元符号($\u0024)。 $字符只能用于机械生成的源代码,或者很少用于访问旧系统上的预先存在的名称。

     

“Java数字”包括ASCII数字0-9(\u0030-\u0039)。

答案 4 :(得分:4)

  

这并没有具体说明不能使用数字,但遗漏的是你可以看到它不被建议。

我当然不会那样阅读Java Style Guide。从Java类库中的众多示例来看,它们都不是。

我想唯一需要注意的是JSG建议使用有意义的名称。并且必然的结果是,只有在语义上有意义时才应使用标识符中的数字。很好的例子是

  • “3D”,
  • “i18n”(==国际化),
  • “2020”(年份),
  • “X509”(标准),依此类推。

甚至“int2Real”也很有意义。


更新

@biziclomp提出了LayoutManager2的案例,并声称2没有任何意义。

以下是javadoc关于此接口用途的说明:

  

LayoutManager的最小扩展名适用于希望创建基于约束的布局的工具提供者。它尚未为基于约束的自定义布局管理器提供完整的一般支持。

据此,我会说名称​​中的2 有意义。基本上,它是说你可以将其视为LayoutManager的继承者。我想这可以用文字说出来,但请参阅上面的例子,说明如何将数字用作简写数字。

@ BlueRaja写道:

  

2没有解释任何内容 - LayoutManager2与LayoutManager有何不同?

风格指南的建议并非名称​​解释事物。相反,它建议它们应该是有意义的。 (有关解释,请参阅javadoc。)显然,有意义是相对的,但是在标识符变得难以阅读和难以输入之前,您可以将其放入标识符中的信息量存在实际限制。

我认为标识符应该提醒读者读者的意思(类,字段,方法等)。

这是一种权衡。

答案 5 :(得分:2)

  

方法应该是动词,混合大小写,首字母小写,每个内部单词的首字母大写。

仅此语法已经表明,他们使用动词的更一般含义而不是通常,其中只有is是动词,session和{{1}是动词。句子意味着像方法名称应该是动词或动词短语,...... ,数字很可能是口头短语的一部分。

这个想法是一个完整的方法调用可以被读作一个完整的句子,主题是点之前的对象,动词是方法名称,其他对象是参数方法:

post

(大多数此类句子可能是质疑或强制性的。)

您的方法名称(从命名约定的角度来看)唯一的问题是句子的主语(会话)不是您方法的if (buffer.isEmpty()) buffer.append(word); 对象,而是一个参数,但这不是用Java避免,我想(请有人证明我错了)。

对于多参数方法,smalltalk方法可以更好地工作:

this

(其中"Hello" replace: "e" with: "x" 是字符串类的一种方法。)

答案 6 :(得分:1)

使用数字本身并不坏,但通常它们并不常见。

在具体情况下,我认为isSessionPost2011(int id) {}不是一个好名字。但是对于将来的使用来说,isSessionPostYear(int id, int year) {}更具可扩展性。

答案 7 :(得分:1)

事实上,它是一种编码约定,动词“应该”的使用建议您允许数字,但建议不要使用方法名称。但是在您的示例中,为什么不将相同的代码概括为?

session.isPostYear(int year);

答案 8 :(得分:1)

我会考虑将你的方法称为别的东西。没有什么可以完全反对数字,但是如果项目的发布日期过后会发生什么?你将有一个名为post2011的方法 - 现在它应该被称为post2012。考虑将其称为postProjNameImplentation而不是吗?

答案 9 :(得分:1)

我在方法名称中使用数字时遇到的唯一问题是它可能表明您的设计中的某些内容可以改进。 (我犹豫说“错了。”)例如,在你的例子中,你说你有一个特定的政策,该政策将在2011年后生效。但是,有一个专门检查那一年的方法似乎过于具体和神奇 - 数年。我建议创建一个通用函数来检查事件是否在Anon建议的指定日期之后发生。

(当我在我的中途时,Anon的答案突然出现,所以我很抱歉,如果我只是复制他所说的话。我觉得我的话扩大了他说的话,所以我想我会无论如何发布它。)

答案 10 :(得分:1)

是的,在某些情况下。例如,您可能想要处理X.509证书。我认为编写一个名为handleX509Certificate的方法是完全可以接受的。

答案 11 :(得分:0)

我不相信本身有理由避免使用标识符中的数字,尽管在您描述的情况下,我不知道我会使用它。相反,我将该方法命名为boolean isPolicyXyzApplicable(int id)

如果这是一项预计会随着时间推移而发生更大变化的政策,请考虑将政策拆分为不同的类别,这样您就不会在方法中长出if(isPolicyX) ... else if(isPolicyY) ... else if(isPolicyZ) ...。一旦将其考虑在内,请使用抽象或接口方法Policy.isApplicableTo(transaction)以及Policy个对象的集合来确定要执行的操作。

答案 12 :(得分:0)

只要你有使用数字的理由,那么imho我认为没关系。

对于您的示例,可能有2个isSessionPost方法,那么您如何命名它们? isSessionPost和isSessionPost2?说实话不太清楚。

请记住,所有名字都必须有意义且你不会出错。

答案 13 :(得分:0)

永远不要忘记 - 规则被打破。唯一的绝对应该是没有绝对。

答案 14 :(得分:0)

我认为在你的情况下可以将它用作一次性标记,特别是如果你希望该方法只能在短时间内存活并最终被弃用。

如果我了解您的用例,您需要将一些旧数据引入到新版本的应用程序中。如果是这种情况,那么一定要添加此方法,将其标记为@deprecated并在更新所有客户端时将其退出。

另一方面,Ralph here有一个有效的观点。不要让这个项目进入2012年:)

答案 15 :(得分:0)

我们一直使用'em,就像你展示的例子一样。也适用于界面版本,例如IConnection2IConnection3

Eclipse也没有抱怨它是非传统的名字。 :)

但可以接受吗?这对你有好处。

答案 16 :(得分:-2)

没有错误

String int2string(int i)

User findUser4Id(long id)

void startHibern8();

哇!这个网站不喜欢这些方法名称!我被捕获了!