Home Variables
Variable type
Choose the type which is most appropriate for the data you are trying to represent. Use
an int
when you only need whole numbers, doubles
when you need
decimal precision, booleans
for when you need a binary true or false value,
Strings
for arbitrary text, and so forth.
Use int
when you only need whole numbers. Use double
when you
need decimal precision. For example:
double numCreditsTaken = 15; // should be a number int scorePercentage = 86; // we probably want decimals
A corrected version would look like so:
int numCreditsTaken = 15; double scorePercentage = 86.2;
If you want an int
to be a double
so that you don't have to
worry about issues with integer division, you should use either multiply your number by 1.0
or use casting, rather then making a separate variable.
public static void foo(int a, int b) { double tempA = a; double tempB = b; return tempA / tempB; }
The corrected version:
public static void foo(int a, int b) { return 1.0 * a / b; // OR // return (double) a / b; }
Don't try and shoehorn variables into something they aren't. For example, don't try and
use a String
or an int
to represent true/false values – that's what
boolean
s are for.
Variable phobia
Make liberal use of variables, especially to eliminate redundant and repeated expressions.
When you have identical expressions that are repeated throughout your method, you should strongly consider using variables to help eliminate that redundancy and to help make your code more concise.
For example, take the following:
public static void drawPixelX( Graphics g, int startX, int startY, int size, int pixelSize) { for (int i = 0; i < size; i++) { g.drawRect( startX + i * pixelSize, startY + i * pixelSize, pixelSize, pixelSize); g.drawRect( startX + (size + 1) * pixelSize - i * pixelSize, startY + i * pixelSize, pixelSize, pixelSize); } }
While this method works correctly (it draws a pixelated "X"), it also has several repeated expressions that could be refactored out.
For example, the expression startY + i * pixelSize
is repeated twice,
the expression i * pixelSize
is repeated four times...
We can also refactor out the expression (size + 1) * pixelSize
. Although
that expression isn't redundant, it does make that particular line longer.
Whenever you see these sorts of repeated expressions, you should refactor them out. For example:
public static void drawPixelX( Graphics g, int startX, int startY, int size, int pixelSize) { int maxWidth = (size + 1) * pixelSize; for (int i = 0; i < size; i++) { int step = i * pixelSize; int currentY = startY + step; g.drawRect(startX + step, currentY, pixelSize, pixelSize); g.drawRect(startX + maxWidth - step, currentY pixelSize, pixelSize); } }
Now, our code is more concise. It's also more readable – by putting complex expressions into variables and giving them distinct names, it's easier for somebody to understand what each equation means.
Scope variables tightly
Scope your variables as tightly as possible – declare them within the smallest set of curly brackets as possible.
When coding, as a general rule of thumb, you want to try and arrange your code so that you minimize the number of factors you need to keep in your head at any given time.
The reason for this is that having to juggle and balance multiple factors adds cognitive load to your brain, making it subtly harder for you to be productive. In fact, it's just like juggling – almost everybody can easily juggle one ball at a time, most people can juggle two, but many people struggle to juggle three balls. The more things you have to keep track of, the harder it is to focus on any one thing.
When we declare variables in a wide scope (when we make variables available to a large segment of our code), we end up increasing the cognitive strain. For example, take the following code:
public static int findNumberOfDentists(Scanner names) { int total = 0; String name = ""; while (names.hasNext()) { name = names.next(); if (isDentist(name)) { total += 1; } } return total; }
Currently, by placing both the total
and name
variable outside
the loop instead of inside, we're implying that there's a good reason to do so –
perhaps we're about to use both variables to preserve information between each iteration?
While this is true of the total
variable, it's untrue of the
name
variable. The value of the name
variable is unique per each
loop, and so should be moved to inside it:
public static int findNumberOfDentists(Scanner names) { int total = 0; while (names.hasNext()) { String name = names.next(); if (isDentist(name)) { total += 1; } } return total; }
This makes it easy to reason about our code. I no longer have to worry if I need to
preserve or do something with the previous value inside the name
variable, and
now know for certain that whatever I do with each name is unique per iteration.
Some beginners will wonder if doing this sort of repeated declaration is potentially inefficient. In reality, it turns out that it isn't – the Java compiler is intelligent enough to detect this sort of thing and automatically optimize it for us to ensure that we incur no penalty in performance.