65

Why should I write (as my collegue says):

import static org.apache.commons.lang.math.NumberUtils.INTEGER_ONE;
if (myIntVariable == INTEGER_ONE) { ... }

instead of:

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

?

I know that the use of constants is recommended but I think the value of NumberUtils.INTEGER_ONE will never change! So I write 1.

Michele
  • 1,213
  • 2
  • 18
  • 36
  • 2
    It would make sense to use in this way, if it was your own custom constant. – Amit.rk3 Jul 17 '15 at 08:37
  • 29
    Maybe you can ask your colleague that question ? He/she may have a particular reason to use it that we don't know. – Florent Bayle Jul 17 '15 at 08:37
  • @FlorentBayle My colleague uses constants EVERYWHERE! He replaces every number or string with a constant! And his answer to my _Why_ is "The documentation says to use constants!"; yes, he is too nitpicking. – Michele Jul 17 '15 at 10:01
  • 5
    @Michele: did you ask *which* documentation says to use constant? – Holger Jul 17 '15 at 15:02
  • Related: http://programmers.stackexchange.com/q/56375/88986 – durron597 Jul 18 '15 at 14:39
  • 2
    The official code conventions mention how to deal with constants. No need to close as "opinion based" when there is an official guideline by the languages designers on how to deal with constants. – josefx Aug 10 '15 at 09:22

7 Answers7

89

You should not. The INTEGER_ONE name is no more meaningful than 1. If however this value has some other meaning (for example, month in the year), then using a constant (like Calendar.FEBRUARY) will make your code clearer.

I can guess that this constant in Commons Math library was created in Java 1.4 when there were no Integer cache and autoboxing, so it had sense in terms that you may reuse the same Integer object (not primitive int) in different places to save memory. So it was added for performance reasons, not for code clarity. Now it's obsolete: even if you need an Integer object, you can use Integer.valueOf(1) or implicit autoboxing and get the cached one.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Tagir Valeev
  • 97,161
  • 19
  • 222
  • 334
  • 20
    But you shouldn't be using `==` for Integer objects. – ratchet freak Jul 17 '15 at 10:19
  • For what it's worth, if using `Calendar.FEBRUARY` is more expressive than `1`, then `INTEGER_ONE` is as well for the same reason, it's making it clear that it's meant simply as an integer and not some sort of ordinal. **Although,** I can't think of a situation where it'd be worth differentiating. – Captain Man Jul 17 '15 at 13:58
  • 4
    @Captain Man: there should be no reason to make clear that a number is meant to be a number as in good code, all literal numbers are meant to be a number as all others are represented by named constants. – Holger Jul 17 '15 at 15:04
  • Ironically, these constants in old code cause the opposite. As such old code uses `new Integer(1)`, it’s the only place, where boxing `1` uses an *unshared* object. – Holger Jul 17 '15 at 15:10
  • @Holger Does "*such old code*" refer to old code in JDK ? I'm curious to see use of `new Integer(1)` as I can't imagine any good reason to use it. – Jean-François Savard Jul 17 '15 at 15:36
  • @Jean-FrançoisSavard, it's about [Commons Math library](http://grepcode.com/file/repo1.maven.org/maven2/commons-lang/commons-lang/2.6/org/apache/commons/lang/math/NumberUtils.java#49). – Tagir Valeev Jul 17 '15 at 15:38
  • @TagirValeev Thanks, for the link. I really don't see any good reason to use `new Integer(1)` except if you hate your code-review team... I'm curious why they did not use `valueOf` instead. – Jean-François Savard Jul 17 '15 at 15:41
  • 3
    @Jean-FrançoisSavard, that's because this library preserves Java 1.4-compatibility which had no `valueOf` method. – Tagir Valeev Jul 17 '15 at 15:42
58

You should not write INTEGER_ONE! Neither should you write 1 (see exception below)!

Why? A literal like 1 is called a magic number. Magic numbers are "unique values with unexplained meaning or multiple occurrences which could (preferably) be replaced with named constants" (explanation from the same Wikipedia page).

So what usually should be done is making those magic numbers to constants whose name represents or explains the meaning of that number. The constant INTEGER_ONE does not explain the meaning.

So what you actually have to do is to find the meaning of the value in this context and create a constant with exactly that name. If the 1 represents the maximum number of allowed threads for example, you should have a constant like:

static final int MAX_NUMBER_OF_THREADS = 1;

EDIT as per Tagir's comment

If the literal itself has a meaning in the domain for which you are writing the code, then it should not be replaced by a named constant. Tagir's example for calculating the inverse element is a good one:

double invert(double x) {
    return 1/x;
}

Here the literal 1 has a meaning in this context inside the math domain. So it can be used as is.

Seelenvirtuose
  • 20,273
  • 6
  • 37
  • 66
  • 1
    That's all good but you have to also reason with yourself on the justification of holding it in it's own variable. You should not do this with all numbers, not in a realistic sense at least. – insidesin Jul 17 '15 at 08:39
  • 1
    @insidesin Oh, and this is wrong. You should do this with nearly all literals that have a meaning. But this is a discussion that probably gets close to being opinion-based. – Seelenvirtuose Jul 17 '15 at 08:40
  • 1
    Like when my professor asks for 'lots of comments' and then gets upset when you ask him what his definition of a lot is... then some people get marked down for having too many. – insidesin Jul 17 '15 at 08:43
  • 7
    What about the method like this: `double invert(double x) {return 1/x;}`? Should I avoid `1` here as well? How to name the constant then? – Tagir Valeev Jul 17 '15 at 09:00
  • @TagirValeev Here the literal itself has a meaning in the domain (math): This calculation is used to get the inverse element. This is an obvious exception to the more general rule. – Seelenvirtuose Jul 17 '15 at 09:02
  • 1
    Well the whole this question seems obvious to me, nevertheless it was asked. So probably you should note in your answer that some obvious exceptions exist. "Neither should you write 1" seems too strict statement for me... – Tagir Valeev Jul 17 '15 at 09:05
  • 1
    @TagirValeev I did that directly after writing my comment. – Seelenvirtuose Jul 17 '15 at 09:07
  • 2
    Actually, in many coding standards I know, 0 and 1 are exempted from the No-Magic_Number rule for good reason, because the often don't represent a number wich can change in the future, but e.g. the presence or absence of something (similar to a bool) – MikeMB Jul 17 '15 at 09:32
  • @MikeMB I would not express the rule based on the value itself, but on the question whether or not the value has an implicit meaning in the current domain. Of course, the values 0 and 1 often have such an implicit meaning. And even if a value can't change (which then is a clear domain rule), this does not mean to not give them an expressive name. In fact, this is all about code readability. – Seelenvirtuose Jul 17 '15 at 09:53
  • @Seelenvirtuose: I agree, 0 and 1 are just the most common literals, that have a clear meaning on their own. Like in the example you provided or e.g. `if (size > 0)`. I think no one would require this to be written as `if (size > NONE)`. – MikeMB Jul 17 '15 at 10:30
  • 0, 1, and occasionally 2 are generally considered acceptable. Magic numbers to be avoided are those which either a) are potentially subject to future change or b) have a meaning which is not immediately obvious to all. Only rarely will 0 or 1 have either of these properties. – Ben Jul 17 '15 at 11:17
  • 8
    @Tagir Valeev: the correct name for the `1` constant in `1/x` is `IDENTITY_ELEMENT_WITH_RESPECT_TO_THE_DIVISION_BINARY_OPERATION`. Don’t be surprised that I also prefer using a literal `1` there… – Holger Jul 17 '15 at 15:15
  • @Holger, I know a developer which uses even longer method and class names. – Tagir Valeev Jul 17 '15 at 15:29
  • 1
    @TagirValeev but dude! Tab completion!! who cares how long the name is? i still type it in ~3 key presses! /s – basher Jul 17 '15 at 16:16
  • @basher: I hate needing horizontal scrollbars when looking at source code… – Holger Jul 17 '15 at 16:20
  • @Holger Agreed. you missed my `/s`. – basher Jul 17 '15 at 16:29
  • I would suggest that literals are also appropriate in many cases where the structure of some code is strongly related to the value. For example, if a routine to sort some portion of a `double[]` will accept any size range, but will most often be called with ranges of 5 or fewer items, using a `switch` and using literal constants for the cases would be entirely reasonable. If a piece of code is going use a hard-coded sequence of comparisons to sort 5 items (such a sequence may be much faster than a loop), labeling that case with the literal `5` will be better than any other identifier. – supercat Jul 17 '15 at 16:49
  • t @TagirValeev In an example where we are assigning a value from an array constan like for default value at subscript 0 from an array constant of 3 elements. we are using var defaultCountryIndia = countries[0]; instead of using 0 we use DEFAULT_COUNTRY_INDEX. So tomorrow even if the position in array changes we just need to modify the constant file. Is this correct from point of view of exceptions for magic number 0 and 1? – Shailesh Vaishampayan May 04 '16 at 19:36
20

I happen to have just written style guidelines for my company and I'd suggest the following:

Don't use hard coded, "magic" values. If a value is constant, define it as such. Numbers such as -1, 0, 1, 2, 100 can be used in some situations.

My examples are in Objective-C as that's the language I was writing guidelines for, but the rules still apply.

Good Usage

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;

Bad Usage

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?
James Webster
  • 31,873
  • 11
  • 70
  • 114
5

org.apache.commons.lang.math.NumberUtils.INTEGER_ONE it gives you a final static Integer object rather than primitive int 1, and as it is final static it acts as a constant and can be used in comparison of Integer objects because will always return same instance.

So in the above scenario it might not look fit but somewhere if you are using it while comparison, it for sure has impact.

Moreover, as much as we can, should prefer the use of constants over hardcoded beacuse:

  1. It can make your code easily maintainable. If any situation occurs in future for change, you can change only at a single place.
  2. The code looks cleaner & more readable.
AnkeyNigam
  • 2,810
  • 4
  • 15
  • 23
  • 4
    I agree with the first part of your answer, but the two general reasons you gave for using constants just don't apply here. – MikeMB Jul 17 '15 at 08:52
  • @MikeMB i provided them not for supporting my statement but as a normal coding convention. – AnkeyNigam Jul 17 '15 at 08:54
  • 3
    Then I'd recommend you reword that part a a bit. At thee moment you are saying: *always prefer constants*, in the context of a question where you should not prefer that constant. – MikeMB Jul 17 '15 at 09:02
  • 1
    @MikeMB edited, Thanks for pointing it out. Its always good to learn from you guys :) – AnkeyNigam Jul 17 '15 at 09:05
  • Re your first paragraph: Does Java consider keys of the same value, but from different origins, to be different when checking containers? If so, that sounds horrible. – underscore_d Jul 17 '15 at 13:17
  • @underscore_d if you are asking regarding this :- `Integer i = new Integer(1);` `Integer k = new Integer(1);` , then here `i`, `k` are different objects. – AnkeyNigam Jul 17 '15 at 17:20
  • @AnkitNigam They may be different objects, but it's not true at all that this "has impact" in `HashMap` or `HashSet`, because they'll compare the same using `.equals`. – Chris Hayes Jul 18 '15 at 07:55
1

You may know whether it will never change, but I won't if I start editing your code...

Basically it's a way of documenting your code in your actual code. The reason to use constants and examples like this is to avoid Magic Numbers in code and their disadvantages.

This being said, you can use it to a point where it is not advantageous anymore and clutter inducing. I tend to do it for things that are used more than once or have the concept of being changed by me or someone else... or in simpler terms important values.

Community
  • 1
  • 1
insidesin
  • 735
  • 2
  • 8
  • 26
  • 8
    I disagree with the magic number argument. `INTEGER_ONE` is always going be 1. – Chetan Kinger Jul 17 '15 at 08:34
  • @CKing What does `INTEGER_ONE` mean? Is it how many times you can guess your login details before the world implodes or is it something simpler? – insidesin Jul 17 '15 at 08:37
  • 9
    That is exactly the point: INTEGER_ONE had no more meaning than a litteral 1, so as far as code clarity and maintainability are concerned it offers no advantages. – MikeMB Jul 17 '15 at 08:50
  • Then the entire question would be irrelevant and his issue would be towards bad variable naming conventions than magic numbers. I was just giving him the benefit of the doubt and assuming his poor variable name was a 'slip of the tongue'. – insidesin Jul 17 '15 at 09:05
  • @insidesin: please note that [it’s not him who named that variable](https://commons.apache.org/proper/commons-lang/javadocs/api-3.1/org/apache/commons/lang3/math/NumberUtils.html#INTEGER_ONE) – Holger Jul 17 '15 at 15:18
  • Yeah @Holger read below for my silly 'doh' moment... well if it's not deleted for you that is, it is for me :| – insidesin Jul 17 '15 at 15:26
1

From Class NumberUtils you'll see it's defined as:

/** Reusable Integer constant for one. */
public static final Integer INTEGER_ONE = new Integer(1)

So, you'll see that INTEGER_ONE is not the same as 1. It's an object that's already been constructed for you. So, if we're needing an instance of Integer(1), rather than create your own, you can reuse the one from the library saving time and memory.

It really depends on your application, if you indeed what the int version of 1, then, you'd probably be better of using that instead of this Integer class.

Stephen Quan
  • 21,481
  • 4
  • 88
  • 75
-4

Imagine that you have this

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

But a few thousand times...

And suddenly in needs to be a 2.

What it easier for you to change?

EDIT: Before downvoting, im answering from the perspective of the advantages of not using magic numbers, im not in any way (i thought this was inferable, come on people) advising to change the library constant.

Ringo
  • 850
  • 9
  • 24
  • 24
    So you expect OP to change the Commons Math library and set INTEGER_ONE to 2 there? – Tagir Valeev Jul 17 '15 at 08:35
  • 8
    so you are suggesting to alter INTEGER_ONE == 2? – Wavemaster Jul 17 '15 at 08:36
  • 8
    I think that the question is more oriented to the use of constants, not the apache specific INTEGER_ONE – Ringo Jul 17 '15 at 08:37
  • 2
    @Luis: On the contrary,the second part shows that this question is explicitly about `INTEGER_ONE` – MikeMB Jul 17 '15 at 08:55
  • @MikeMB There is no proof that he meant to name his variable poorly or not and will not be any help until you ask him (hence no argument here, completely on the fence, neither of you are right or wrong) – insidesin Jul 17 '15 at 09:07
  • 4
    @insidesin: He didn't name the constant it comes from the library. And that constant is NOT poorly named. It's purpose is to serve as a number of a certain type (different from the litteral 1). It's purpose was never to be a descriptive name for a certain parameter (which is what most people think of when they say "prefer constants"). So all arguments for not using 1 directly in the code because it is a magic number also apply directly to INTEGER_ONE, plus it is more boilerplate and thus less readable. Tagir Valeev explains, why it's also no longer necessary from a performance point of view. – MikeMB Jul 17 '15 at 09:27