开发者

Why is it wrong to use numbers in Java method names?

Sometime ago, I remember being told not to use numbe开发者_StackOverflow社区rs in Java method names. Recently, I had a colleague ask me why and, for the life of me, I could not remember.

According to Sun (and now Oracle) the general naming convention for method names is:

Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

Code Conventions of Java

This doesn't specifically say that numbers can't be used, although by omission you can see that it's not advised.

Consider the situatiuon (that my colleague has) where you want to perform some logic based on a specific year, for instance, a new policy that takes affect in 2011, and so your application must act on the information and process it based on it's year. Common sense could tell you that you could call the method:

boolean isSessionPost2011(int id) {}

Is it acceptable to use numbers in method names (despite the wording of the standard)? If not, why?

Edit: "This doesn't specifically say that numbers can't be used, although by omission you can see that it's not advised." Perhaps I worded this incorrectly. The standard says 'Methods should be verbs'. I read this to say that considering a number is not a verb, then method names should not use numbers.


The standard Java class library is full of classes and methods with numbers in it, like Graphics2D.


The method seems ... overly specific.

Couldn't you instead use:

boolean isSessionAfter(int id, Date date)

?

That way the next time you have a policy applied to anything after a particular date, you don't need to copy-paste the old method and change the number - you just call it with a different date.


Sure, it's acceptable to use numbers in method names. But as per your example, that's why it's generally frowned upon. Let's say that there is now a new policy in place for the year 2012. Now, there's a new policy in place for 2014. And maybe 2020! So, you have four methods that are roughly equivalent.

What you want isn't a boolean but rather a strategy to do something, or do nothing, based on whether or not a policy was found. Hence, a method void processPolicy(Structure yourStructure); would be a better approach - now you can shield that you're doing a lookup based on the year, and don't have to have separate methods per year, or even limit it to just one policy per year (maybe a policy takes place in two different years, for example, or just three months).


The Java Language Specification seems fairly specific on this topic:

3.8 Identifiers

An identifier is an unlimited-length sequence of Java letters and Java digits, the first of which must be a Java letter.

...

The Java letters include uppercase and lowercase ASCII Latin letters A-Z (\u0041-\u005a), and a-z (\u0061-\u007a), and, for historical reasons, the ASCII underscore (_, or \u005f) and dollar sign ($, or \u0024). The $ character should be used only in mechanically generated source code or, rarely, to access preexisting names on legacy systems.

The "Java digits" include the ASCII digits 0-9 (\u0030-\u0039).


This doesn't specifically say that numbers can't be used, although by omission you can see that it's not advised.

I certainly wouldn't read the Java Style Guide that way. And judging from numerous examples in the Java class libraries, neither do they.

I guess the only caveat is that the JSG recommends use of meaningful names. And the corollary is that you should only use numbers in identifiers when they are semantically meaningful. Good examples are

  • "3D",
  • "i18n" ( == internationalization ),
  • "2020" (the year),
  • "X509" (a standard), and so on.

Even "int2Real" is meaningful in a folksy way.


UPDATE

@biziclomp has raised the case of LayoutManager2, and claims that the 2 conveys no meaning.

Here's what the javadoc says about the purpose of this interface:

This minimal extension to LayoutManager is intended for tool providers who wish to the creation of constraint-based layouts. It does not yet provide full, general support for custom constraint-based layout managers.

From this, I would say that the 2 in the name is meaningful. Basically, it is saying that you can view this as a successor to LayoutManager. I guess that could have been said in words, but see the examples above on how numbers where numbers are used as short-hand.

@ BlueRaja writes:

The 2 does not explain anything - how is LayoutManager2 any different from LayoutManager?

The advice of the Style Guide is NOT that names should explain things. Rather, it advises that they should be meaningful. (For the explanation, refer to the javadoc.) Obviously meaningfulness is relative, but there is a practical limit on the amount of information you can put into an identifier before it becomes hard to read and hard to type.

My take is that the identifier should remind the reader what the meaning of the thing (class, field, method, etc) that is named.

It is a trade-off.


Methods should be verbs, in mixed case with the first letter lowercase, with the first letter of each internal word capitalized.

This phrasing alone already shows that they use a more general meaning of verb than the usual, where only is would be the verb, neither session nor post are verbs. The sentence means something like Method names should be verbs or verbal phrases, ..., and numbers can very well be parts of verbal phrases.

The idea is that a complete method call can be read as a complete sentence, with the subject being the object before the dot, the verb being the method name, and additional objects being the arguments to the method:

if (buffer.isEmpty()) 
    buffer.append(word);

(Most such sentences would be either questioning or imperative ones.)

Your method name has (from a naming convention viewpoint) the only problem that the subject of the sentence (the session) is not the this object of your method, but an parameter, but this can't be avoided with Java, I think (please someone prove me wrong).

For multiple-parameter methods the smalltalk approach would work better:

"Hello" replace: "e" with: "x"

(where replace:with: is one method of the string class.)


Yes, in some circumstances. For example, maybe you want to handle X.509 certificates. I think it would be perfectly acceptable to write a method called handleX509Certificate.


The only problem I see with using numbers in method names is that it may be an indication that something in your design could be improved upon. (I hesitate to say "is wrong.") For instance, in your example, you stated that you have a specific policy which comes into effect after 2011. However, having a method specifically to check for that year seems overly specific and magic-number-y. I'd instead suggest creating a generalized function to check if an event occurred after a specified date as Anon suggested.

(Anon's answer popped up while I was halfway through mine, so my apologies if it seems like I'm just duplicating what he said. I felt that mine expanded on what he was saying a bit, so I thought I'd post it anyway.)


I would consider calling your method something else. Nothing against numbers exactly, but what happens if the project slips it release date? You'll have a method called post2011 - when it should be called post2012 now. Consider calling it postProjNameImplentation instead maybe?


The use of number it is not bad itself, but usually they are not very common.

in the specific case, I don't think isSessionPost2011(int id) {} is a good name. but it is better isSessionPostYear(int id, int year) {} more extensible for future uses.


The fact it is a coding convention and the use of the verb "should" suggest you that digits are permitted but advised against in methods names. However in your example, why not generalizing the same code as?

session.isPostYear(int year);


We use 'em all the time, like the example you showed. Also for interface versions, like IConnection2 and IConnection3.

Eclipse doesn't complain that it's a nontraditional name, either. :)

But acceptable? That's kind-of up to you.


Don't ever forget - rules are made to be broken. The only absolute should be that there are no absolutes.


I don't believe there's a per se reason to avoid numbers in identifiers, although in the case you describe, I don't know that I'd use it. Rather, I'd name the method something like boolean isPolicyXyzApplicable(int id).

If this is a policy that's expected to change more over time, consider splitting policies out into different classes so you don't end up growing a long vine of if(isPolicyX) ... else if(isPolicyY) ... else if(isPolicyZ) ... in your methods. Once this is factored out, use an abstract or interface method Policy.isApplicableTo(transaction) and a collection of Policy objects to determine what to do.


As long as you have a reason for using numbers, then imho I think it's fine.

For your example, there might be 2 isSessionPost method, so how would you name them? isSessionPost and isSessionPost2? Not very clear to be honest.

Just remember that all names must be meaningful and you won't go wrong.


I think in your case it's OK to use it as a one-off marker, specifically if you expect that the method will only live for a short period of time and eventually be deprecated.

If I understand your use case, you need to bring in some legacy data into the new version of your application. If this is the case, then definitely add this method, mark it @deprecated and retire it when all your clients are updated.

On the other hand Ralph here has a valid point. Don't let this project to slip into 2012 :)


nothing is wrong

String int2string(int i)

User findUser4Id(long id)

void startHibern8();

wow! this website doesn't like these method names! I got captchaed!

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜