count
field is static in the Counter
class, it means you can reference the variable with the following expression: Counter.count
.
![10 things you need to know about the static modifier in Java - 1](https://cdn.codegym.cc/images/article/29ca201b-1465-4321-a547-ee6d8e33e1ec/1024.jpeg)
private
fields are available only within the class in which they are declared. And protected
fields are available to all classes within a package, as well as to all their subclasses outside the package.
Suppose the Counter
class has a static increment()
method whose job is to increment the count
field. To call this method, you can use Counter.increment()
. There is no need to create an instance of the Counter
class to access a static field or method. This is the fundamental difference between static (class) variables and methods and NON-static (instance) variables and methods.
An important note. Don't forget that the static members of the class directly belong to the class, not any instance of the class. That is, the value of the static count
variable will be the same for all Counter
objects. In this article, we'll look at the fundamental aspects of using the static modifier in Java, as well as some features that will help you understand key programming concepts.
What every programmer should know about the static modifier in Java.
In this section, we look at the main aspects of using static methods, fields, and classes. Let's start with the variables.You CANNOT access non-static members of a class within a static context, such as a static method or block. Compiling the code below will result in an error:
public class Counter { private int count; public static void main(String args []) { System.out.println(count); // Compile time error } }
This is one of the most common mistakes made by Java programmers, especially newbies. Since the
main
method is static and thecount
variable is not, using theprintln
method inside themain
method will produce a "compile time error".Unlike local variables, static fields and methods are NOT
thread safe
in Java. In practice, this is one of the most frequent causes of security problems in multi-threaded programming. Considering that each instance of a class references the same copy of a static variable, such a variable needs to be protected or "locked" by the class. Therefore, when using static variables, be sure that they are properlysynchronized
to avoid problems such asrace conditions
.Static methods have a practical advantage in that there is no need to create a new object each time you want to call them. A static method can be called using the name of the class that declares it. That's why these methods are perfect for
factory
methods andutility
methods. Thejava.lang.Math
class is a wonderful example: almost all its methods are static. Java's utility classes are markedfinal
for the same reason.Another important point is that you can't override (
@Override
) static methods. If you declare such a method in asubclass
, i.e. a method with the same name and signature, you just "hide" the method of thesuperclass
instead of overriding it. This phenomenon is known asmethod hiding
. This means that if a static method is declared in both parent and child classes, the method called will always be based on the variable type at compile time. Unlike with method overriding, such methods will not be executed when the program runs. Let's consider an example:class Vehicle { public static void kmToMiles(int km) { System.out.println("Inside the parent class / static method"); } } class Car extends Vehicle { public static void kmToMiles(int km) { System.out.println("Inside the child class / static method"); } } public class Demo { public static void main(String args []) { Vehicle v = new Car(); v.kmToMiles(10); } }
Console output:
Inside the parent class / static method
The code clearly demonstrates that despite the fact that the object is a
Car
, the static method in theVehicle
class is called, since the method was called at compile time. And note that there were no compilation errors!What's more, other than top-level classes, you can declare classes static. Such classes are known as
nested static classes
. They are useful for providing better cohesion. A striking example of a nested static class isHashMap.Entry
, which is a data structure insideHashMap
. It is worth noting that, like inner classes, static nested classes are declared in a separate .class file. Thus, if you declare five nested classes in your main class, you will have 6 files with the .class extension. Another example is the declaration of our ownComparator
, such as an age comparator (AgeComparator
) in theEmployee
class.The static modifier can also be specified in a static block, better known as a "static initialization block", which is executed when the class is loaded. If you don't declare such a block, Java collects all static fields into a single list and initializes them when the class is loaded. A static block CANNOT throw checked exceptions, but it can throw unchecked ones. In this case, an
ExceptionInInitializerError
will occur. In practice, any exception that occurrs during initialization of static fields will be wrapped in this error by Java. This is also the most common cause of theNoClassDefFoundError
, because the class won't be in memory when it is referenced.It's useful to know that static methods are linked at compile time, unlike the linking of virtual or non-static methods, which are linked at run time when called on a real object. Accordingly, static methods cannot be overridden in Java, since polymorphism does not apply to them at run time. This is an important limitation to consider when declaring a method static. Doing so makes sense only when there is no ability or need to override the method in a subclass. Factory methods and utility methods are good examples of proper use of the static modifier. Joshua Bloch points out several advantages that static factory methods have over constuctors in his book Effective Java, which is mandatory reading for every Java programmer.
Initialization is an important aspect of a static block. Static fields or variables are initialized after the class is loaded into memory. The order of initialization is from top to bottom, in the same order in which they are declared in the source file of the Java class. Since static fields are initialized in a thread-safe manner, this process is also used to implement the
Singleton
pattern. If you are not using anEnum
as aSingleton
for some reason, then you have a good alternative. But in this case, you must take into account that this is not a "lazy" initialization. This means that the static field will be initialized even BEFORE someone "asks" for it. If an object is resource-heavy or rarely used, then initializing it in a static block won't work in your favor.During serialization, static fields, like
transient
variables, are not serialized. Indeed, if you save any data in a static field, it will contain its initial (default) value after deserialization. For example, if a static field is anint
, its value will be zero after deserialization. If its type isfloat
, the value will be 0.0. If the field is anObject
, the value will benull
. To be honest, this is one of the most frequently asked questions about serialization in interviews for Java positions. Don't store essential object data in a static field!Finally, let's talk about static import. This modifier has a lot in common with the standard
import
statement, but it is different in that it lets you mport one or all static class members. Once static methods are imported, they can be accessed as if they were declared in the same class. Similarly, by importing static fields, we can access them without specifying the class name. This feature appeared in Java 1.5 and improves code readability when used properly. This construct is found most often in JUnit tests, since almost all test developers use static import for assert methods, e.g.assertEquals()
and their overloaded variants.That's all for now. Every Java programmer needs to know all of the aspects of the static modifier mentioned above. This article reviewed basic information about static variables, fields, methods, initialization blocks, and imports. It also touched on some important properties that are essential to know to write and understand Java programs. I hope that every developer will perfect their skillful use of static members, because it's very important for serious software development."