Turning Bad Coding Habits into Lessons
We all have bad habits. Some of us bite our nails, other folks like to chew with their mouth open. One of my bad habits is that I can be lazy when I’m trying to bang out some code too quickly.
I know, I know – as a Supreme Coding Guru I should know better. In my defense, my code ends up being neat and well-written. It just starts very sloppy and lackadaisical.
One of my worst coding tendencies is that I use a lot of the same variable names over and over.
int j. int i. int num. String string. Each shows up at least 5 or 6 times in any given program.
In my early days of coding, this led to a lot of issues. I would run my code, expect one thing to happen, and watch as something else occurred. I would trace through my code and get even more confused.
When you name all of your variables the same, it is very easy to get lost. You can quickly lose track of what variable you are following. Basically, it becomes hard to track who is doing what.
BUT this isn’t technically a programming problem. Sometimes it actually makes sense to name multiple variables the same thing.
But what about when you’re new to coding and have no clue how variable scope work? Yeah, then it might be a problem.
Fear not coders, as today we will answer these questions. First, we need to understand exactly what it means when we say “local” and “global” variables. Furthermore, we will learn the difference between local and global variables and why this is an important concept to grasp.
Dive Right In
I like using analogies, and from the feedback I get, you guys tend to like my analogies too. With that great segue, let’s jump into an analogy.
Imagine you’re living the high life, enjoying a nice Saturday at your mansion. Let’s pretend its still summer, so you’re out relaxing in a swimming pool. You’re soaking in the rays and pondering whether the California drought is still a thing. After a bit of alone time, your friend decides to join you
You guys are laughing and having a good time, but then your friend makes a request of you. “Hey,” they say, “can you give me the pool noodle?”.
You panic. You think to yourself, “What pool noodle?”.
Your friend didn’t say “Give me the green pool noodle” or “Give me that pool noodle”, just “Give me the pool noodle”.
Let’s imagine that you are as awkward as me, and you don’t want to ask “What pool noodle?” and risk looking foolish.
So what do you do?
You look about frantically, when suddenly you see it. A pool noodle is bobbing up and down at the other end of the pool. You swim over to it and grab it.
Here goes nothing. You swim over to your friend and present them with the noodle. You wait a moment for their reply.
“Thank you,” your friend says. (We are assuming your friend has good manners).
That wasn’t so bad, right?
Your friend asked for the pool noodle and you managed to find one nearby. The problem was solved. But wait – let’s rewind and re-imagine that scenario really quickly.
Let’s imagine that there wasn’t a pool noodle in the pool. If you still don’t want to have to ask your friend for clarification, what would you do then?
What I imagine would happen is you would look beyond the pool. Maybe you sit in the pool, peer around the yard, and see a noodle resting behind a tree. If that were to fail maybe you’d gaze back towards the mansion. Perhaps you see a noodle inside, leaning against a window.
In fact, that is probably the order we would use pool noodles. If there were three pool noodles on the property (one in the pool, one in the backyard, and one in the house), we would probably retrieve them for our friend in that order.
What I mean is, if our friend says “Bring me the pool noodle”, we would assume they mean the one already in the pool. Why?
Because we are already in the pool so that noodle is closest.
If there weren’t one in the pool, we would guess they mean the one in the yard. (Because that is the next closest).
If there wasn’t a noodle in both the pool and yard, we would guess they meant the one in the house. (Because that is the only option).
This is a smart assumption to make – that the closest pool noodle is the one our friend is talking about. On top of that, it saves you energy when you have to go running to retrieve it.
This concept helps describe the scope of variables. Basically, it has to do with finding the thing that our friend (the user) asks for that is also closest to where Java currently is within a program.
Scoping Out the Scene
As we said before, there are two levels of scope for variables. When we say scope, we basically mean to say “reach”, as in, how far this variable can be “seen” and used.
Global variables are ones that we define at the very beginning of our program and are accessible everywhere within our program.
This is because since we declare these variables first, outside of any other sub-classes or methods, Java assumes you want this variable to apply to EVERYTHING in your code. This means that we can have a function, within a class, within a class, within a program (we’re diving deep, like Inception) and we would still be able to access our global variables.
Local variables, on the other hand, are defined within a class or function within the program and can only be accessed within the area that they are defined. This can be a bit tougher to explain, so let’s think of it this way:
Think back to our pool noodles. Remember how when we were in the pool, we said we might be able to see a noodle in the pool, one behind a tree, and one hidden in the house?
What You See is What You Get
Well imagine that when we step out of the pool, the noodle in the pool is no longer visible. The noodle behind the tree and the one in the house both are still visible, however. If we walk into the house and peer out the window, both the noodle in the pool and the one behind the tree are no longer visible.
Basically, no matter where you are you can see the noodle that is in the house. To see the other noodles however, you have to be near them.
This is how variables and scope work within Java. Once Java is “out of the pool”, the noodle in the pool doesn’t exist to it anymore. This is because Java doesn’t want to waste its energy looking inside of every bit of code. Instead, when you call a variable it will look for it inside of whatever block it is currently in. If that fails, it will move out of the block.
If you are yelling “BRING ME THE POOL NOODLE” and Java is standing in the yard, the only two noodles Java might bring you are the one in the yard or the one in the house. Again, this is because is Java is looking for something, it will only widen its search, not narrow it.
If you need Java to retrieve the pool noodle that is in the pool, then Java needs to be in the pool. It’s the same as your friend asking you to get the pool noodle, you can’t grab the noodle in the pool from inside of the house.
Well then, you might ask, how come Java needs to be in the pool to get that noodle, but Java can be in the pool and still know about the tree noodle and the one in the house?
This all comes back to scope. Basically, a block of a program “knows” about the blocks that it is inside of, but doesn’t know much about the blocks inside of it.
In the analogy we used, we can say the biggest block is the house, and then the backyard is inside of that block, and then the pool is inside of the backyard block. We say this because the pool is in the backyard, and the backyard is a part of the overall house.
Examples of Scope in Java
Here is a snippet of code that I wrote that helps illustrate what I mean.
In this snippet of code, the biggest block is My_Mansion, which holds My_Backyard, which holds My_Pool. Each of these three classes has a variable named String poolNoodle.
Now notice that if I tried to make another String poolNoodle in any of these three blocks I would receive an error. This would be because Java sees I’ve already declared String poolNoodle. I am allowed, however, to declare String poolNoodle ONCE in each block of code.
Why? Because even though they are all named exactly the same, Java sees each as it’s own separate variable.
Key Point: Java will always look for variables by moving to OUTER blocks.
If we asked to print out poolNoodle, Java would use whichever poolNoodle is nearest. This means if we asked to print it out while inside of the My_Backyard class, it would print “The noodle in the yard”.
If we were within the My_Pool class, it would print “The noodle in the pool”.
Since My_Mansion is the outermost scope-level, that means that if we instead wrote our code like this, all three of these classes would use the poolNoodle in My_Mansion, because it is the nearest one that each class can still see.
(This is a slightly complex example because we are using inner-classes here, but there would still be ways to access the poolNoodle from My_Backyard and My_Pool).
That is the idea of global vs local variables at their most basic:
It is simply Java’s way of finding a variable if we do not explicitly say which one we want and if there are more than one variables of that type with that name (ex, we had three String variables named poolNoodle).
3 Things to Know About Global and Local Variables
Now that we understand how global and local variables work, let’s recap some quick tips about their proper use.
1. Global Variables Aren’t That Useful (Most of the time)
Yes, it’s true – global variables don’t do a ton for us. In your early days of programming where all of your code is contained in one class, global variables can prove to be useful. Once you expand your reach, however, it becomes less useful to have global variables.
Because global variables take up space and memory and time because Java creates and waits to use them. So if we have a global variable that gets used for one thing, and then never gets used in any case again, it might just be taking up space doing something a local variable could’ve done.
A good habit is to go through your code and figure out where variable’s scope are best suited. Does that global variable really need to be accessed by everyone? Or should that local variable maybe be moved so that it has more folks able to see it?
Both of these are questions worth asking.
2. Local Variables Might Stop Existing
Let me clarify what I mean.
Local variables can be created in a way where Java destroys them after use. Not destroys, I guess, but rather Java lets them float off into the ether. When does this happen?
Mostly if the variable is created and used within a function or method. If we have a function called countToThree() and within the function we create a variable called myCurrentNumber, then once the function begins, myCurrentNumber is created and used. Once the function is over, myCurrentNumber doesn’t exist anymore.
If we run the function again, myCurrentNumber will be created from scratch all over again. This is something worth knowing as a lot of early programmers get confused why Java doesn’t save the data from these local variables. The answer is because these variables only exist when and as long as they are in use.
3. Global Versus Local Variables Matter the Most When We Re-Use Names
What we mean here is that if we only had ONE variable named String poolNoodle in our whole program, Java doesn’t have to “guess” which poolNoodle you want.
Global and local variables are good concepts to understand, but keep in mind they will confuse you the most when you are using multiple variables of the same type with the same exact name.
When you are like me and have thirty int nums in your code, it quickly gets confusing which one is being called by whom. But if you choose to use some better naming conventions (ex: String housePoolNoodle, String yardPoolNoodle, String poolPoolNoodle), you can save yourself some headaches.
Bear in mind though, the rules still apply of scope. You can create the only String poolNoodle in the My_Pool area, and then try to call it from outside of the pool (My_Backyard or My_Mansion). Even if there is only ONE variable of that type and name, Java still needs to be in the right area of the program to see and use it.
Where Do We Go From Here?
Global and local variables (and the idea of scope) are concepts I was glad to have figured out when I did. A lot of your early programs will suffer from issues related to scope, so the sooner you can figure it out, the better.
What do you think? Is this concept super confusing still, or was it something that always made a lot of sense to you? Let me know down in the comments.