static variables and methods might better have been called perClass variables and methods. They inherited this misleading terminology from C++. They are the opposite of instance variables and methods that
work on a particular object.
There is nothing static (unchanging) about them. They don’t cling. They are perfectly clear, unlike
radio signals garbled by static.
They are allocated when the class is loaded. static refers to a method or
variable that is not attached to a particular object, but rather to the class as a whole.
static final when applied to a variable is Javanese for "constant". All
static methods are automatically final. It is not
strictly speaking an error to mark them final, but it is redundant and considered
bad form.
static methods work without any this object.
static methods are limited to calling other static
methods in the class and to using only static variables. They can call instance
methods only if they use their own object references — not rely on this..
static methods and variable are in a sense inherited, but not in the same strong
sense that instance variables and methods are. You can refer to Dog.bark() as
Dalmatian.bark() if no one has written a Dalmatian.bark().
However, if you use Dog.bark() you always get the Dog
version and if you say Dalmatian.bark() you always get the Dalmatian version.
Newbies tend to overuse static variables. Consider what would happen if your code were used by several threads
simulaneously. With shared static variable they would trip over each other. With local and instance variables
they often would not, even without any special sychronisation. Sometimes, of course, you do need the globalness
of static variables, but don’t use it where it would make more sense to create
a object to track each chain of calculation.
Static typing
The word static is used in a second context, the opposite of dynamic or
runtime type. This refers to the compile-time declared type of a variable, compared with the run time
actual type it points to. e.g. a Dog variable may point to a Dalmatian object, but not vice versa. The static type (the type of the reference) is Dog and the dynamic type (the type of the object) is Dalmatian. You will
often hear Java referred to a language with static type checking. The types of all
references are checked for consistency at compile time.
Static Loading
The word static is used in a third context. It refers to ordinary classes explicitly
mentioned in the code. Dynamic classes are loaded on-the-fly using Class.forName where
the class name is constructed as a String.
Static Web Pages
The word static is used in a fourth context. It refers to web pages the server sends
out unchanged. Dynamic pages are modified or even composed from scratch before sending.
Static Nested Classes
Finally, Java has an obscure feature where you can also declare nested classes static. This does not mean all their methods are static, or that they cannot be instantiated,
rather it means you instantiate the inner classes independently of the main enclosing class. There is no
associated outer class object. Such classes are often called nested static classes.
Non-static inner class objects always have an associated outer class object.
Avoiding Static
When you first learn Java, there is a tendency to overused static because it simpler and faster. However, often
this choice is not good in the long run. Here are two situation to ovoid static.
- Conceivably would a user use this class for more than one task simultaneously? If you have any static variables they will clash with such use. Better to make the them instance variables
and instantiate a instance of the class for each task, even when there is only one.
- It is very easy to put all configuration constants in a class, then refer to them thoughout the app. To
change the static configuration constants you modify the source and recompile.
What if at some point in future, your program needs maintain more than one configuration, or to alternate
between configurations as it processes different files, or even runs one thread with one configuration and
another thread with a different configuration. You won’t be able to use that technique. So if that is a
possibility, it is best to write your configuration as a class that implements an interface with getter
functions. It might still use static final constants to back those getters.
Learning More