This was a Moodle posting in 2011, originally written by then-tutors
Andys Chinery & Ridge.
12 February 2012
Please can everyone read through this even if they are pretty sure
they know what they are doing - just because your code is working
doesn't mean it's right!
Over the years we've that noticed a lot of people are getting
confused about the static keyword in Java. That's understandable,
lots of people (myself included) did the same thing when they
learned, so we want to try to clear it up.
To reiterate: in Java you have classes, and objects. Objects are
instances of classes. So if you like, the class provides a
specification for the individual object: "objects of this class
should have these fields, they should be able to do these methods".
Static methods and variables are stored at a class level rather than
an instance level. That's the official line, but what does it mean?
If a field is stored at the object (instance) level, in other words
it is not static, then every individual version of that
object has its own version of that field. Think about the class Integer,
as you know, this is the object version of the primitive int. If you
don't understand that, don't worry: an Integer is just a number.
Every Integer has a value. So if you say new Integer(5);
then you get an Integer with value 5, and if you say new
Integer(200); you get an Integer with value 200. Every
Integer has its own value, it wouldn't make sense for them to share
one. So it is stored at the object level.
However there is only one maximum value of Integer. In the
normal version of Java, that value is 2147483647. Instead of having
to remember that, you can look at the static field Integer.MAX_VALUE.
From anywhere, you can always check what the maximum value of
Integer is. This exists at the class level, because it is
related to the class, and there is only one.
So to recap, for fields that relate to individual objects, don't
use static. For those that apply to every instance of an object, it
might make sense to use static. The same goes for methods.
If you're unsure, it almost definitely shouldn't be static.
One of the reasons this is confusing is because you are trying to do
things in the main method (which is static) without creating
instances. The compiler complains that things need to be static, but
it is wrong.
Here are some very arbitrary examples of using
static. The first, is an example of what people tend to do when
they don't understand static:
public
class StaticMonkey
{
private
static boolean hasBanana = true;
public
static void eatBanana()
{
if(hasBanana){
System.out.println("that
was nice");
hasBanana
= false;
}
else {
System.out.println("Uh
oh, I don't have a banana");
}
}
public
static void main(String[] args)
{
StaticMonkey.eatBanana();
StaticMonkey.eatBanana();
}
}
Which this one will print out "that was nice" followed by "Uh oh, I
don't have a banana" because the static variable hasBanana
exists at the class
level so there is only ever one of them. This is only ever set to
true once. You should
also notice that we don't actually create any instances of StaticMonkey
here.
And now what you should be doing:
public
class Monkey
{
private
boolean hasBanana = true;
public
void eatBanana()
{
if(hasBanana){
System.out.println("that
was nice");
hasBanana
= false;
}
else {
System.out.println("Uh
oh, I don't have a banana");
}
}
public
static void main(String[] args)
{
Monkey
brian = new Monkey();
brian.eatBanana();
Monkey
dave = new Monkey();
dave.eatBanana();
}
}
This will print out "that was nice" twice
because the variable hasBanana is associated with
each object we create, and (overall) is set twice, once when Brian is
created once when Dave is created.
The reason that this doesn't cause any issues in the current
piece of coursework is that you are (probably) only going to
need one instance of each class. However, if your dungeon were
multiplayer, and you had a Player class that you needed
multiple instances of, then putting static everywhere
would cause you serious issues.