How do I get rid of magic numbers in java without declaring a massive amount of finals or static finals? Keep in mind looping, arrays are not allowed. It doesn't seem possible? Help appreciated. thanks.
Example code:
drawOval(5, 5, width, height); drawOval(10, 10, width, height); drawOval(15, 15, width, height); drawOval(20, 20, width, height); drawOval(25, 25, width, height); 83 Answers
Defining constants is really your only option. What's your opposition to using them? They are definitely worth their space in this context. Future developers would much rather see extra constants than be confused by what those numbers mean.
2The direct answer is that named constants is the only way to avoid having magic numbers in your code.
But the flip-side is that it is debatable whether magic numbers are harmful or the extent that they are harmful. And in this particular case it is debatable whether these actually qualify as "magic" numbers ... at least, IMO.
Lets illustrate this:
// Alternative #1 private final int PLACE_1_X = 5; private final int PLACE_1_Y = 5; ... drawOval(PLACE_1_X, PLACE_1_Y, width, height); // Alternative #2 drawOval(5, 5, width, height); Which of these is actually more readable? Does defining named constants (which are most likely at a different point in the source code!) make it easier to understand what is going on? Don't you now have the problem that you have to look in two places not one to understand what a specific drawOval call is going to draw?
The bottom line is that the "no magic numbers" dogma only really applies when it meaning of the numbers is not self-evident from the context ... or when the number is actually a repeatedly used constant. (Like if we were going to use PLACE_1 lots of times in the same "picture".)
You need to think about the context, not just blindly apply the dogma.
An alternative to finals / static that I've already seen is to use a custom object as an argument:
public void drawOval(OvalArg arg) { // ... } OvalArg arg = new OvalArg(); arg.first = 10; arg.second = 10; arg.width = 100; arg.height = 500; drawOval(arg); However, this approach implies that you cannot see directly which arguments must be sent to a method (unless you look into the argument object), and requires extra validation to ensure that your custom object is correctly filled. For that reason, I would recommend using constants.
2