[Newbie Question] Magic Number's dangerous?

S

seungwoo.yu

Hello, All

There are many magic numbers located in our java source code.
Someone pointed out that this is not good coding style.
What dangerous appeared? used Magic Numbers

Thanks
 
C

clarke.jonathan

hmm....Let me be the first to say "huh"?

perhaps your refering to the mythical magic number beast that lives
within the MS java VM. Its sole mission is to eat decent java code?
 
M

Mike Gaab

Hello, All

There are many magic numbers located in our java source code.
Someone pointed out that this is not good coding style.
What dangerous appeared? used Magic Numbers

Thanks

IMO, the worst thing is that it makes your code hard to read, and
therefore it is hard to understand. Numbers standing alone communicate
little to nothing except for a maybe a 0 or 1. Then it follows that your
code will be hard to maintain and can be error prone.

That's my two cents worth.
Mike
 
M

Mike Gaab

hmm....Let me be the first to say "huh"?

perhaps your refering to the mythical magic number beast that lives
within the MS java VM. Its sole mission is to eat decent java code?

A magic number is simply a number in your source.
For example, let's say we were tracking days of a week.

short dayOfWeek = 4;

4 is a magic number. It really has no meaning, does it mean it is the 4th
day
of the week or the 5th day of the week? We don't know by just looking at
it. Surely we could find out by hunting through other source code but that
is
a waste of time. So we could do the following. [brute force but you
get the idea]

public static final short Sun= 0;
public static final short Mon = 1;
public static final short Tues = 2;
public static final short Wed = 3;
public static final short Thurs= 4;
public static final short Fri = 5;
public static final short Sat = 6;
....
short dayOfWeek = Thur;

Now this makes the code easy to read and understand which makes your
code easier to maintain.

Mike
 
C

clarke.jonathan

Ahh ok.

Knew the concept however I never realised that it was known as Magic
Numbers. Was someone in Sun smoking something at the time when they
came up with that name I wonder?
 
R

Roedy Green

There are many magic numbers located in our java source code.
Someone pointed out that this is not good coding style.
What dangerous appeared? used Magic Numbers

The problem is in maintenance. If someone changes them they may
change literals in not enough or too many places. With named
constants there is one place to fix and it is clearly labelled what
the constant means. In context in code it is not as clear.
 
G

grubbyfans

though it takes place to store static final variables it's useful to
maintain the source code and modify
 
G

Gordon Beaton

But only if the number or string has the same semantic meaning. If
two numbers appear and happen to be the same value, but one could
change independently of the other, it doesn't make sense to
artificially tie them together.

I know, that should fall under the common sense, but as in other
things, common sense isn't as common as it should be.

I remember discovering the following during a code review:

#define ONE 1
#define TWO 2
#define THREE 3
[...]

....all the way to a hundred or so.

I asked the programmer if he thought that any of these values might
need to change one day (no), or if he could tell me what any of them
meant (only by looking at the code where they were used).

Nobody had ever explained to him the *purpose* of using symbolic
constants, just that it was a bad idea to have the values themselves
directly in the code.

/gordon
 
T

Thomas Hawtin

There are many magic numbers located in our java source code.
Someone pointed out that this is not good coding style.
What dangerous appeared? used Magic Numbers

It is often the case that programmers get over draconian when it comes
to magic numbers. With a new hammer, everything becomes a nail.

If you need to allocate a buffer, it's better to write:

byte[] buff = new byte[8192];

(and use buff.length rather than repeating the number) than to write:

/**
* Size of buffer private to {@link #xyzFunction}.
*/
private static final SOME_BUFFER_LENGTH = 8192;

.... screens later ...

byte[] buff = new byte[SOME_BUFFER_LENGTH];

As a rule of thumb, if a number *or string* appears twice, always give
it a constant (or preferably eliminate subsequent appearances). For
other cases, use common sense.

Tom Hawtin
 
A

Alan Krueger

Thomas said:
If you need to allocate a buffer, it's better to write:

byte[] buff = new byte[8192];

(and use buff.length rather than repeating the number) than to write:

/**
* Size of buffer private to {@link #xyzFunction}.
*/
private static final SOME_BUFFER_LENGTH = 8192;

... screens later ...

byte[] buff = new byte[SOME_BUFFER_LENGTH];

In my experience, this seems to be a carryover from coding in C/C++
where you can't always tell the size of a buffer from the buffer itself.
But this, then, fires the rule you mention next:
As a rule of thumb, if a number *or string* appears twice, always give
it a constant (or preferably eliminate subsequent appearances). For
other cases, use common sense.

But only if the number or string has the same semantic meaning. If two
numbers appear and happen to be the same value, but one could change
independently of the other, it doesn't make sense to artificially tie
them together.

I know, that should fall under the common sense, but as in other things,
common sense isn't as common as it should be.
 
Z

zero

public static final short Sun= 0;
public static final short Mon = 1;
public static final short Tues = 2;
public static final short Wed = 3;
public static final short Thurs= 4;
public static final short Fri = 5;
public static final short Sat = 6;
...
short dayOfWeek = Thur;

Now this makes the code easy to read and understand which makes your
code easier to maintain.

Mike

Since 1.5 it might be better to use enums.

enum DayOfWeek { Sun, Mon, Tues, ...

Not sure how thos affects performance though, and for something simple this
may be overkill.
 
T

Thomas Hawtin

Since 1.5 it might be better to use enums.

enum DayOfWeek { Sun, Mon, Tues, ...

Not sure how thos affects performance though, and for something simple this
may be overkill.

Overkill? Seems to reduce quantity and improves clarity of the code.

Performance is unlikely to matter.

Tom Hawtin
 
Z

zero

Overkill? Seems to reduce quantity and improves clarity of the code.

Performance is unlikely to matter.

Tom Hawtin

Probably, but I haven't seen any tests (or done any myself) so I'd rather
say that it *might* be an issue than just ignore it and possibly give
someone bad information.
 
M

Mike Gaab

Thomas Hawtin said:
Overkill? Seems to reduce quantity and improves clarity of the code.

I am not up on recent Java features but I did look at the enum type prior to
deciding to use named constants in the example above. Seemed to me like
using Java enums confused the issue as they don't appear to be implemented
as they are in many other languages. Not that implementing them differently
is a bad thing , just not implemented as one would expect. For instance, how
do I assign a value to each element? What are the default values? In the
case above one could expect the values to be Sun=0, Mon=1 and so on but at a
quick glance they did not appear to have those values. How do I get at each
elements value to possibly re-assign its value?

Since you are up to speed on enums, how about an example.

Mike
 
R

Roedy Green

For instance, how
do I assign a value to each element? What are the default values?

see http://mindprod.com/jgloss/enum.html
to answer your basic questions.

Java numbers them automatically.

If you want some other numbers or values, you can define a method and
implement it for each enum constant, or pass it is the constructor and
use a method common to all enum constants.
 
L

Lasse Reichstein Nielsen

Mike Gaab said:
I am not up on recent Java features but I did look at the enum type prior to
deciding to use named constants in the example above. Seemed to me like
using Java enums confused the issue as they don't appear to be implemented
as they are in many other languages. Not that implementing them differently
is a bad thing , just not implemented as one would expect. For instance, how
do I assign a value to each element?

Like you assign values to other objects:
---
enum EnumWithAValue {
FOO(2),
BAR(42),
BAZ(87);

public final int value;
EnumWithAValue(int value) {
this.value = value;
}
}

// .... FOO.value == 2
---
You can also assign more than one value to each instance.

What are the default values?

There are none. The elements of an enumeration have nothing to
distinguish themselves by except their object identity (well, they do
have a name and an ordinal, but that's really implementation details).
In the case above one could expect the values to be Sun=0, Mon=1 and
so on but at a quick glance they did not appear to have those
values.

Correct. Java enumerations define a type with a fixed number of
values. It does so using a class with a fixed number of instances.

C-like languages instead define a fixed number of integer constants.
There is no type, so you cannot declare a variable to only take
members of the enumeration as values. I.e., the Java way is type-safe,
the C one is not.

The Java enumeration implementation is taken from the way people were
already implementing type-safe enums. It was explained in, e.g.,
"Java Language Programming Guide" by Joshua Bloch (Item 21 IIRC).
How do I get at each elements value to possibly re-assign
its value?

If you really want to be able to change it, make a settable value on
each instance. Otherwise, just set value by the constructor.

It really is just a class and instances of it. What makes it an enum
is that there can only be a fixed number of instances. (A singleton
is really just a trivial enumeration)

/L
 
M

Monique Y. Mudama

There are many magic numbers located in our java source code.
Someone pointed out that this is not good coding style.
What dangerous appeared? used Magic Numbers

It is often the case that programmers get over draconian when it comes
to magic numbers. With a new hammer, everything becomes a nail.

If you need to allocate a buffer, it's better to write:

byte[] buff = new byte[8192];

(and use buff.length rather than repeating the number) than to write:

/**
* Size of buffer private to {@link #xyzFunction}.
*/
private static final SOME_BUFFER_LENGTH = 8192;

... screens later ...

byte[] buff = new byte[SOME_BUFFER_LENGTH];


Seems like you're dodging the issue here by giving a poor example.
The fact is that you must have chosen 8192 for a reason, and that
reason can be documented with a well-chosen variable name.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top