608

What is a magic number?

Why should it be avoided?

Are there cases where it's appropriate?

Mark Amery
  • 143,130
  • 81
  • 406
  • 459
Adam Davis
  • 91,931
  • 60
  • 264
  • 330
  • 6
    You would avoid magic numbers cause other people viewing your code might not understand why you're doing what you're doing... e.g. `const myNum = 22; const number = myNum / 11;` right now my 11 could be people or bottles of beer or something so instead I would change 11 to a constant such as inhabitants. –  Sep 17 '19 at 11:03
  • Using magic numbers in attributes is unavoidable, so I guess this is appropriate. – donatasj87 Oct 23 '19 at 12:31

15 Answers15

696

A magic number is a direct usage of a number in the code.

For example, if you have (in Java):

public class Foo {
    public void setPassword(String password) {
         // don't do this
         if (password.length() > 7) {
              throw new InvalidArgumentException("password");
         }
    }
}

This should be refactored to:

public class Foo {
    public static final int MAX_PASSWORD_SIZE = 7;

    public void setPassword(String password) {
         if (password.length() > MAX_PASSWORD_SIZE) {
              throw new InvalidArgumentException("password");
         }
    }
}

It improves readability of the code and it's easier to maintain. Imagine the case where I set the size of the password field in the GUI. If I use a magic number, whenever the max size changes, I have to change in two code locations. If I forget one, this will lead to inconsistencies.

The JDK is full of examples like in Integer, Character and Math classes.

PS: Static analysis tools like FindBugs and PMD detects the use of magic numbers in your code and suggests the refactoring.

Lii
  • 11,553
  • 8
  • 64
  • 88
Marcio Aguiar
  • 14,231
  • 6
  • 39
  • 42
  • 207
    0 and 1 are exceptions to this rule. – Jonathan Parker Apr 07 '09 at 23:35
  • 48
    @Jonathan Parker, except when they're not (`TRUE`/`FALSE`) – Brendan Long Jun 02 '10 at 03:11
  • 107
    Just because a magic number will never change doesn't mean it shouldn't be replaced by a constant. My code is full of global constants like HzPerMHz and msecPerSecond. These will never change, but they make the meaning clearer, and provide some protection against typos. – Jeanne Pindar Jun 03 '10 at 23:33
  • 8
    other good natural constants include ONE_MINUTE = 60, ONE_HOUR = 3600, ONE_DAY = 86400 (most programmers will be working with epoch times)... or –  Aug 28 '13 at 15:49
  • 6
    I'd say that that code is LESS readable, why would you want to have to go hunting for the definition of MAX_PASSWORD_SIZE when it won't change? you're literally just making it more spaghettish. – MarcusJ Feb 18 '14 at 02:36
  • 2
    @BrendanLong It doesn't always have to be `TRUE` / `FALSE` as exception. Example: `if(array.length == 0)` (or `< 1`) – das Keks Apr 08 '14 at 14:06
  • 16
    ... It is essential to get in the habit of defining constants to give meaning to otherwise "arbitrary" numbers, even in trivial methods, where it seems obvious. Why? Because in the future, that method may get added to. What at first seemed obvious, is now somewhere within many lines of code. As for being spaghettish, AFAIK all decent modern IDEs make it trivial to find the value of a constant variable. Usually can just hover over any use of the variable. And even back in the day, when we didn't have such niceties, it was very, very worth it, in the long run. – ToolmakerSteve Sep 29 '14 at 00:26
  • 7
    What about things like: `connection.setTimeout(50);` Should `50` be a constant here? It seems to be pretty clear, that `50` is a connection timeout – Sergey Kolodyazhnyy Dec 12 '14 at 14:05
  • All good and well but the thing is, when using hibernate criteria.list() you often get arrays of Object and then I won't use a constant to indicate the index position of the record field... :-P – Lawrence Mar 20 '15 at 15:31
  • 9
    @Sergey _"What about things like: connection.setTimeout(50); Should 50 be a constant here? It seems to be pretty clear, that 50 is a connection timeout"_ - It's a magic number regardless of a single or multiple call. Why 50? Why not 51? You may need to change it because you're deploying to an environment which requires different timeouts. I'd much rather change a constant than hunt through code. –  Apr 09 '15 at 09:47
  • 1
    Hmm, just ran into this while implementing a hashCode() where you frequently have magic numbers not used elsewhere. Now lint forces me to add a constant which IMHO doesn't improve readability at all. lint is right 99% of the time ant 1% of the time it really sux. – Michael Apr 24 '15 at 22:06
  • 4
    Using magic numbers directly is is not a bad thing on itself. A lot of mathematical formulas consist of magic numbers, really, **a lot**. The same mathematics where computers and software are build upon. It is just more useful to refer to number *which might be refactored in the future* using a variable. Therefor this answer is just too simplistic by my opinion. Try to implement simple physics this way, you will know what I mean. – Tim Oct 26 '15 at 15:57
  • @Lawrence you can still use a constant there is no disadvantage IMHO, because if you create a "define class" for this which just does just contain the constants you will only need to go there an change it instead of hunt down all spots with the same string. Also you could chain them with `String.Format()` (C#) or what ever so you could do `public const string CELLPosition= "ROW{0}Col{1}"` and then simply `String.Format(CELLPosition,row,col)` and you get what you want. – WiiMaxx Feb 11 '16 at 08:28
  • 1
    What about this particular case? `const passwordExpiresAt = moment().add(2, 'days').toDate();` Do I really need some constant `PASSWORD_EXPIRE_TIME_IN_DAYS` defined? This is only used in one spot in the code, and the 2's meaning is clearly gathered from the rest of the line. If I later change it to 1 or 3, the meaning is still obvious. – Merlin -they-them- Dec 07 '16 at 07:21
  • 5
    `1` and `0` can still be magic numbers, it just depends on context. Checking `if someArray.length === 0` the purpose is obvious, you're checking if it's empty, it's not considered a magic number. But then if you do `createSomething(1)`, that's a magic number. There's no way to get from context what that 1 is about - especially when that `1` acts as a `boolean`. If you had a `true` or `false`, it's clear that this parameter is on or off. – tdtm Jan 22 '19 at 01:06
  • 3
    @MickyD: To me a number is magic only if its meaning is not explicit. I do not understand why you'd think you wouldn't be asking yourself the exact same question ("why 50 and not 51") if the number was defined as a constant. As for the future change requirement, I would argue YAGNI (but the day you need it, yes by all means, refactor it to a constant). – AgentCorleone Feb 21 '19 at 07:34
  • 1
    @AgentCorleone it has nothing to do with _"meaning"_, _explicit_ or otherwise. It is to do with hard-coded values in the code. If the same value is used more than once in the code it should be `defined as a constant` 1) to be sure your code is in sync 2) in the event you wish to change it easily in the `future` which a good developer should always be thinking about. YAGNI, being a proponent of the undisiplined _lets-just-ship-it-out-the-door_, goes against long-term thinking. So I'm not surprised YAGNIs are doing it –  Feb 21 '19 at 14:18
  • @MickyD: Well according to the Wikipedia definition (which seems to me like a pretty decent source), it clearly mentions "unexplained meaning"... And I surely did say you should use constants when the value is used in multiple places, that is just common sense. My point was, as for everything in the programming area, you have to be pragmatic about it. There is a huge difference between `password.length() > 7`, which is not self-explanatory at all, and `connection.setTimeout(50)` where the intention is totally clear. – AgentCorleone Feb 22 '19 at 08:16
  • As for the YAGNI principle, I stand by it, in the timeout case, simply because "refactoring" it to a constant, if needed, couldn't be more quick and easy to do. I do understand the necessity of "Long-term thinking" when speeking about a business rule (like a password minimum length) or an architecture boundary, but here, it's just a pure technical parameter. – AgentCorleone Feb 22 '19 at 08:28
  • Wow, just came across this, so re- one of the early comments: a HUNDRED_PERCENT could easily be a valuable constant! for a percentage with 1/100 precision (0.01%-99.99%) you could use a HUNDRED_PERCENT=10000. If you always used that constant when converting to and from decimal, it would work great. – Bill K Feb 28 '19 at 01:03
  • I've found and magic constant in Integer.class `if (radix == 10) { return toString(i); }` – Alex78191 Jul 18 '19 at 17:48
178

A Magic Number is a hard-coded value that may change at a later stage, but that can be therefore hard to update.

For example, let's say you have a Page that displays the last 50 Orders in a "Your Orders" Overview Page. 50 is the Magic Number here, because it's not set through standard or convention, it's a number that you made up for reasons outlined in the spec.

Now, what you do is you have the 50 in different places - your SQL script (SELECT TOP 50 * FROM orders), your Website (Your Last 50 Orders), your order login (for (i = 0; i < 50; i++)) and possibly many other places.

Now, what happens when someone decides to change 50 to 25? or 75? or 153? You now have to replace the 50 in all the places, and you are very likely to miss it. Find/Replace may not work, because 50 may be used for other things, and blindly replacing 50 with 25 can have some other bad side effects (i.e. your Session.Timeout = 50 call, which is also set to 25 and users start reporting too frequent timeouts).

Also, the code can be hard to understand, i.e. "if a < 50 then bla" - if you encounter that in the middle of a complicated function, other developers who are not familiar with the code may ask themselves "WTF is 50???"

That's why it's best to have such ambiguous and arbitrary numbers in exactly 1 place - "const int NumOrdersToDisplay = 50", because that makes the code more readable ("if a < NumOrdersToDisplay", it also means you only need to change it in 1 well defined place.

Places where Magic Numbers are appropriate is everything that is defined through a standard, i.e. SmtpClient.DefaultPort = 25 or TCPPacketSize = whatever (not sure if that is standardized). Also, everything only defined within 1 function might be acceptable, but that depends on Context.

Samuel
  • 2,106
  • 1
  • 17
  • 27
Michael Stum
  • 177,530
  • 117
  • 400
  • 535
  • 27
    Even if it can't change it's still a bad idea because it's not clear what's going on. – Loren Pechtel Jun 02 '10 at 03:41
  • 21
    It's not always unclear. `SmtpClient.DefaultPort = 25` is possibly clear*er* than `SmtpClient.DefaultPort = DEFAULT_SMTP_PORT`. – user253751 Nov 09 '14 at 10:53
  • 7
    @immibis I suppose that is assuming that there is absolutely no other code that uses the concept of DEFAULT_SMTP_PORT. If the default SMTP port for that application is changed, then it would need to be updated in multiple places causing the possibility of inconsistency. – Russ Bradberry Apr 01 '15 at 15:47
  • 5
    It's also harder to find all usages - you'd have to search for `25` all over the application and make sure you only change the occurrences of `25` that are for the SMTP Port, not the 25's that are e.g. the width of a table column or the number of records to show on a page. – Michael Stum Apr 01 '15 at 19:57
  • 4
    In that example, I'd expect the code to use SmtpClient.DefaultPort, not 25. So you'd just have to change it in one place. And the port number is likely to remain the same, it's not a random magic number, but a number assigned by `IANA`. – njsg Jun 08 '15 at 06:59
43

Have you taken a look at the Wikipedia entry for magic number?

It goes into a bit of detail about all of the ways the magic number reference is made. Here's a quote about magic number as a bad programming practice

The term magic number also refers to the bad programming practice of using numbers directly in source code without explanation. In most cases this makes programs harder to read, understand, and maintain. Although most guides make an exception for the numbers zero and one, it is a good idea to define all other numbers in code as named constants.

MarianD
  • 13,096
  • 12
  • 42
  • 54
somas1
  • 1,156
  • 1
  • 16
  • 23
35

Magic Number Vs. Symbolic Constant: When to replace?

Magic: Unknown semantic

Symbolic Constant -> Provides both correct semantic and correct context for use

Semantic: The meaning or purpose of a thing.

"Create a constant, name it after the meaning, and replace the number with it." -- Martin Fowler

First, magic numbers are not just numbers. Any basic value can be "magic". Basic values are manifest entities such as integers, reals, doubles, floats, dates, strings, booleans, characters, and so on. The issue is not the data type, but the "magic" aspect of the value as it appears in our code text.

What do we mean by "magic"? To be precise: By "magic", we intend to point to the semantics (meaning or purpose) of the value in the context of our code; that it is unknown, unknowable, unclear, or confusing. This is the notion of "magic". A basic value is not magic when its semantic meaning or purpose-of-being-there is quickly and easily known, clear, and understood (not confusing) from the surround context without special helper words (e.g. symbolic constant).

Therefore, we identify magic numbers by measuring the ability of a code reader to know, be clear, and understand the meaning and purpose of a basic value from its surrounding context. The less known, less clear, and more confused the reader is, the more "magic" the basic value is.

Basics

We have two scenarios for our magic basic values. Only the second is of primary importance for programmers and code:

  1. A lone basic value (e.g. number) from which its meaning is unknown, unknowable, unclear or confusing.
  2. A basic value (e.g. number) in context, but its meaning remains unknown, unknowable, unclear or confusing.

An overarching dependency of "magic" is how the lone basic value (e.g. number) has no commonly known semantic (like Pi), but has a locally known semantic (e.g. your program), which is not entirely clear from context or could be abused in good or bad context(s).

The semantics of most programming languages will not allow us to use lone basic values, except (perhaps) as data (i.e. tables of data). When we encounter "magic numbers", we generally do so in a context. Therefore, the answer to

"Do I replace this magic number with a symbolic constant?"

is:

"How quickly can you assess and understand the semantic meaning of the number (its purpose for being there) in its context?"

Kind of Magic, but not quite

With this thought in mind, we can quickly see how a number like Pi (3.14159) is not a "magic number" when placed in proper context (e.g. 2 x 3.14159 x radius or 2Pir). Here, the number 3.14159 is mentally recognized Pi without the symbolic constant identifier.

Still, we generally replace 3.14159 with a symbolic constant identifier like Pi because of the length and complexity of the number. The aspects of length and complexity of Pi (coupled with a need for accuracy) usually means the symbolic identifier or constant is less prone to error. Recognition of "Pi" as a name is a simply a convenient bonus, but is not the primary reason for having the constant.

Meanwhile: Back at the Ranch

Laying aside common constants like Pi, let's focus primarily on numbers with special meanings, but which those meanings are constrained to the universe of our software system. Such a number might be "2" (as a basic integer value).

If I use the number 2 by itself, my first question might be: What does "2" mean? The meaning of "2" by itself is unknown and unknowable without context, leaving its use unclear and confusing. Even though having just "2" in our software will not happen because of language semantics, we do want to see that "2" by itself carries no special semantics or obvious purpose being alone.

Let's put our lone "2" in a context of: padding := 2, where the context is a "GUI Container". In this context the meaning of 2 (as pixels or other graphical unit) offers us a quick guess of its semantics (meaning and purpose). We might stop here and say that 2 is okay in this context and there is nothing else we need to know. However, perhaps in our software universe this is not the whole story. There is more to it, but "padding = 2" as a context cannot reveal it.

Let's further pretend that 2 as pixel padding in our program is of the "default_padding" variety throughout our system. Therefore, writing the instruction padding = 2 is not good enough. The notion of "default" is not revealed. Only when I write: padding = default_padding as a context and then elsewhere: default_padding = 2 do I fully realize a better and fuller meaning (semantic and purpose) of 2 in our system.

The example above is pretty good because "2" by itself could be anything. Only when we limit the range and domain of understanding to "my program" where 2 is the default_padding in the GUI UX parts of "my program", do we finally make sense of "2" in its proper context. Here "2" is a "magic" number, which is factored out to a symbolic constant default_padding within the context of the GUI UX of "my program" in order to make it use as default_padding quickly understood in the greater context of the enclosing code.

Thus, any basic value, whose meaning (semantic and purpose) cannot be sufficiently and quickly understood is a good candidate for a symbolic constant in the place of the basic value (e.g. magic number).

Going Further

Numbers on a scale might have semantics as well. For example, pretend we are making a D&D game, where we have the notion of a monster. Our monster object has a feature called life_force, which is an integer. The numbers have meanings that are not knowable or clear without words to supply meaning. Thus, we begin by arbitrarily saying:

  • full_life_force: INTEGER = 10 -- Very alive (and unhurt)
  • minimum_life_force: INTEGER = 1 -- Barely alive (very hurt)
  • dead: INTEGER = 0 -- Dead
  • undead: INTEGER = -1 -- Min undead (almost dead)
  • zombie: INTEGER = -10 -- Max undead (very undead)

From the symbolic constants above, we start to get a mental picture of the aliveness, deadness, and "undeadness" (and possible ramifications or consequences) for our monsters in our D&D game. Without these words (symbolic constants), we are left with just the numbers ranging from -10 .. 10. Just the range without the words leaves us in a place of possibly great confusion and potentially with errors in our game if different parts of the game have dependencies on what that range of numbers means to various operations like attack_elves or seek_magic_healing_potion.

Therefore, when searching for and considering replacement of "magic numbers" we want to ask very purpose-filled questions about the numbers within the context of our software and even how the numbers interact semantically with each other.

Conclusion

Let's review what questions we ought to ask:

You might have a magic number if ...

  1. Can the basic value have a special meaning or purpose in your softwares universe?
  2. Can the special meaning or purpose likely be unknown, unknowable, unclear, or confusing, even in its proper context?
  3. Can a proper basic value be improperly used with bad consequences in the wrong context?
  4. Can an improper basic value be properly used with bad consequences in the right context?
  5. Does the basic value have a semantic or purpose relationships with other basic values in specific contexts?
  6. Can a basic value exist in more than one place in our code with different semantics in each, thereby causing our reader a confusion?

Examine stand-alone manifest constant basic values in your code text. Ask each question slowly and thoughtfully about each instance of such a value. Consider the strength of your answer. Many times, the answer is not black and white, but has shades of misunderstood meaning and purpose, speed of learning, and speed of comprehension. There is also a need to see how it connects to the software machine around it.

In the end, the answer to replacement is answer the measure (in your mind) of the strength or weakness of the reader to make the connection (e.g. "get it"). The more quickly they understand meaning and purpose, the less "magic" you have.

CONCLUSION: Replace basic values with symbolic constants only when the magic is large enough to cause difficult to detect bugs arising from confusions.

General Grievance
  • 4,555
  • 31
  • 31
  • 45
Liberty Lover
  • 844
  • 10
  • 12
  • 3
    Thanks. Fwiw the static analysis tools my colleagues keep installing keep complaining about magic numbers - but how is a tool supposed to understand semantics? The result is ALL basic values are replaced with symbolic constants. As I agree with your conclusion I find this less than ideal. – Chomeh Oct 09 '19 at 00:25
  • 1
    Symbolic `PI` should used rather than `3.14159` for two reasons: 1. It prevents typos. The compiler will catch if the constant is misspelled, but not if a digit in the number is missing or wrong. Having the number in one place is less error prone. Ideally that place would be from a math library that is used by many projects. 2. It ensures that your entire application uses the same value of PI, with enough significant figures. Having some places use `3.14` and other places `3.14159` can lead to bugs. Ideally your definition would have the maximum significant figures allowed by your data type. – Stephen Ostermiller Aug 24 '22 at 15:34
22

A magic number is a sequence of characters at the start of a file format, or protocol exchange. This number serves as a sanity check.

Example: Open up any GIF file, you will see at the very start: GIF89. "GIF89" being the magic number.

Other programs can read the first few characters of a file and properly identify GIFs.

The danger is that random binary data can contain these same characters. But it is very unlikely.

As for protocol exchange, you can use it to quickly identify that the current 'message' that is being passed to you is corrupted or not valid.

Magic numbers are still useful.

Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • 18
    I don't think that's the magic number he was refering to – Marcio Aguiar Sep 06 '08 at 22:32
  • 5
    Maybe you should remove the "file-format" and "networking" tags you added because he's clearly not talking about those kinds of magic numbers. – Landon Sep 06 '08 at 22:42
  • 12
    It's still very useful to know that magic numbers may refer to more than simply a code issue. -Adam – Adam Davis Sep 07 '08 at 00:13
  • 3
    If the subject read: "What is a magic number in terms of source code" then the tags shouldn't be there. But he did not specify this. So having my extra information is good. I think Kyle, Landon and Marcio are wrong. – Brian R. Bondy Sep 13 '08 at 20:17
  • 4
    There was also no way to determine which one he was looking for. Since I was the first post I couldn't guess which one he was looking for. – Brian R. Bondy Sep 13 '08 at 20:19
20

In programming, a "magic number" is a value that should be given a symbolic name, but was instead slipped into the code as a literal, usually in more than one place.

It's bad for the same reason SPOT (Single Point of Truth) is good: If you wanted to change this constant later, you would have to hunt through your code to find every instance. It is also bad because it might not be clear to other programmers what this number represents, hence the "magic".

People sometimes take magic number elimination further, by moving these constants into separate files to act as configuration. This is sometimes helpful, but can also create more complexity than it's worth.

Nick Retallack
  • 18,986
  • 17
  • 92
  • 114
  • Can you be more specific on why eliminating maginc numbers ISN'T alway good? – Marcio Aguiar Sep 06 '08 at 23:00
  • In math formulas like e^pi + 1 = 0 – Jared Updike Sep 08 '08 at 22:32
  • I think he meant it isn't always good to move magic numbers to config files, which I agree. – Mike Stone Sep 18 '08 at 10:17
  • 5
    Marcio: When you do things like "const int EIGHT = 8;" and then requirements change and you end up with "const int EIGHT = 9;" – jmucchiello Mar 03 '09 at 18:50
  • 10
    Sorry, but that's simply an example of bad naming, or a base usage for the constant. – Kzqai Aug 06 '10 at 01:06
  • 3
    @MarcioAguiar: On some platforms, an expression like `(foo[i]+foo[i+1]+foo[i+2]+1)/3` may be evaluated much faster than a loop. If one were to replace the `3` without rewriting the code as a loop, someone who saw `ITEMS_TO_AVERAGE` defined as `3` might figure they could change it to `5` and have the code average more items. By contrast, someone who looked at the expression with the literal `3` would realize that the `3` represents the number of items being summed together. – supercat Mar 30 '15 at 22:00
  • 2
    How about `quadratic_root = (-b + sqrt(b*b - 4*a*c)) / (2*a)`? Really any mathematical formula where the "magic numbers" don't have meaning beyond their inclusion in the formula. – jodag May 01 '18 at 00:02
13

A problem that has not been mentioned with using magic numbers...

If you have very many of them, the odds are reasonably good that you have two different purposes that you're using magic numbers for, where the values happen to be the same.

And then, sure enough, you need to change the value... for only one purpose.

  • This doesn't look all that probable when talking about numbers (at least not to me), but I ran into it with strings and it is a hit: first you have to read a lot of code to see where its used, than you have to notice that it's being used for different things...not my favourite pastime. – Tomislav Nakic-Alfirevic Jul 24 '14 at 14:58
12

A magic number can also be a number with special, hardcoded semantics. For example, I once saw a system where record IDs > 0 were treated normally, 0 itself was "new record", -1 was "this is the root" and -99 was "this was created in the root". 0 and -99 would cause the WebService to supply a new ID.

What's bad about this is that you're reusing a space (that of signed integers for record IDs) for special abilities. Maybe you'll never want to create a record with ID 0, or with a negative ID, but even if not, every person who looks either at the code or at the database might stumble on this and be confused at first. It goes without saying those special values weren't well-documented.

Arguably, 22, 7, -12 and 620 count as magic numbers, too. ;-)

Sören Kuklau
  • 19,454
  • 7
  • 52
  • 86
9

I assume this is a response to my answer to your earlier question. In programming, a magic number is an embedded numerical constant that appears without explanation. If it appears in two distinct locations, it can lead to circumstances where one instance is changed and not another. For both these reasons, it's important to isolate and define the numerical constants outside the places where they're used.

Community
  • 1
  • 1
Kyle Cronin
  • 77,653
  • 43
  • 148
  • 164
5

I've always used the term "magic number" differently, as an obscure value stored within a data structure which can be verified as a quick validity check. For example gzip files contain 0x1f8b08 as their first three bytes, Java class files start with 0xcafebabe, etc.

You often see magic numbers embedded in file formats, because files can be sent around rather promiscuously and lose any metadata about how they were created. However magic numbers are also sometimes used for in-memory data structures, like ioctl() calls.

A quick check of the magic number before processing the file or data structure allows one to signal errors early, rather than schlep all the way through potentially lengthy processing in order to announce that the input was complete balderdash.

DGentry
  • 16,111
  • 8
  • 50
  • 66
2

It is worth noting that sometimes you do want non-configurable "hard-coded" numbers in your code. There are a number of famous ones including 0x5F3759DF which is used in the optimized inverse square root algorithm.

In the rare cases where I find the need to use such Magic Numbers, I set them as a const in my code, and document why they are used, how they work, and where they came from.

Rob Rolnick
  • 8,519
  • 2
  • 28
  • 17
  • 2
    In my opinion, the magic number code smell refers specifically to *unexplained* constants. As long as you're putting them in a named constant, it shouldn't be a problem. – Don Kirkby Sep 17 '08 at 05:43
1

What about initializing a variable at the top of the class with a default value? For example:

public class SomeClass {
    private int maxRows = 15000;
    ...
    // Inside another method
    for (int i = 0; i < maxRows; i++) {
        // Do something
    }

    public void setMaxRows(int maxRows) {
        this.maxRows = maxRows;
    }

    public int getMaxRows() {
        return this.maxRows;
    }

In this case, 15000 is a magic number (according to CheckStyles). To me, setting a default value is okay. I don't want to have to do:

private static final int DEFAULT_MAX_ROWS = 15000;
private int maxRows = DEFAULT_MAX_ROWS;

Does that make it more difficult to read? I never considered this until I installed CheckStyles.

Ascalonian
  • 14,409
  • 18
  • 71
  • 103
  • 1
    I think this would be okay if the constructor initializes the value. Otherwise if the value is initialized outside of the constructor, I just see it as a hassle and as something harder to read. – Thomas Eding Jun 02 '10 at 04:25
  • I think `static final` constants are overkill when you're using them in one method. A `final` variable declared at the top of the method is more readable IMHO. – Eva Mar 05 '13 at 23:25
0

Another advantage of extracting a magic number as a constant gives the possibility to clearly document the business information.

public class Foo {
    /** 
     * Max age in year to get child rate for airline tickets
     * 
     * The value of the constant is {@value}
     */
    public static final int MAX_AGE_FOR_CHILD_RATE = 2;

    public void computeRate() {
         if (person.getAge() < MAX_AGE_FOR_CHILD_RATE) {
               applyChildRate();
         }
    }
}
jguiraud
  • 21
  • 5
0

@eed3si9n: I'd even suggest that '1' is a magic number. :-)

A principle that's related to magic numbers is that every fact your code deals with should be declared exactly once. If you use magic numbers in your code (such as the password length example that @marcio gave, you can easily end up duplicating that fact, and when your understand of that fact changes you've got a maintenance problem.

Andrew
  • 11,894
  • 12
  • 69
  • 85
  • 6
    IOW code should be written like this: `factorial n = if n == BASE_CASE then BASE_VALUE else n * factorial (n - RECURSION_INPUT_CHANGE); RECURSION_INPUT_CHANGE = 1; BASE_CASE = 0; BASE_VALUE = 1` – Thomas Eding Jun 02 '10 at 04:17
-1

What about return variables?

I specially find it challenging when implementing stored procedures.

Imagine the next stored procedure (wrong syntax, I know, just to show an example):

int procGetIdCompanyByName(string companyName);

It return the Id of the company if it exists in a particular table. Otherwise, it returns -1. Somehow it's a magic number. Some of the recommendations I've read so far says that I'll really have to do design somthing like that:

int procGetIdCompanyByName(string companyName, bool existsCompany);

By the way, what should it return if the company does not exists? Ok: it will set existesCompany as false, but also will return -1.

Antoher option is to make two separate functions:

bool procCompanyExists(string companyName);
int procGetIdCompanyByName(string companyName);

So a pre-condition for the second stored procedure is that company exists.

But i'm afraid of concurrency, because in this system, a company can be created by another user.

The bottom line by the way is: what do you think about using that kind of "magic numbers" that are relatively known and safe to tell that something is unsuccessful or that something does not exists?

ROMANIA_engineer
  • 54,432
  • 29
  • 203
  • 199
Oskytar
  • 205
  • 2
  • 8
  • In that specific case, if the documentation of the function states that a negative return value means no company was found, then there's no reason for using a constant. – Vincent Fourmond Jul 18 '15 at 09:34