Bits of Java – Episode 14: The static keyword
In this episode we will discuss the meaning of the static keyword and we will see where it can be used in your code.
There are various places in your code when you can use the static keyword. Let’s see them.
staticfields: when you mark a variable asstaticyou are creating a class variable, meaning that the variable is shared among all the instances of the class in which is defined. This is in contrast with instance variables, which are non-static variables defined within a class, and of which every instance of the class gains its own copy.
public class MyClass {
public static int counter = 0; //this is a class (static) variable
public int number; //this is an instance (non-static) variable
public static void main(String[] args) {
MyClass instance1 = new MyClass();
instance1.counter = 1;
instance1.number = 30;
MyClass instance2 = new MyClass();
instance2.counter = 2;
instance2.number = 40;
/*
* Both these statement will print 2, because counter is a class variable,
* meaning each instance share the same variable
*/
System.out.println(instance1.counter);
System.out.println(instance2.counter);
/*
* The first statement will print 30 and the second 40. number is an
* instance variable, meaning every instance of the class gets its own
* number variable and modify such variable for one instance does not
* affect the value for the other instance
*/
System.out.println(instance1.number);
System.out.println(instance2.number);
}
}
Since static variables are shared among all the instances, we actually do not need any instance to call them. We just need the class to be loaded, and that`s it!
public class MyClass {
public static int counter = 0; //this is a class (static) variable
public static void main(String[] args) {
//We do not need any instance of the class to call a static variable!
System.out.println(MyClass.counter);
}
}
This is probably the most common way to access a static variable. What you may not know (I did not, at least) is that you can also do something like this:
public class MyClass {
public static int counter = 0; //this is a class (static) variable
public static void main(String[] args) {
MyClass instance1 = new MyClass();
System.out.println(instance1.counter); //prints 0
instance1 = null;
System.out.println(instance1.counter); //still prints 0
}
}
Here we are setting the instance of MyClass to null, but accessing a static variable through a null instance is still possible and does not throw any runtime Exception. This is because, being a class variable, it exists and it is accessible also if the instance is null as long as the class is loaded!
staticinitializer blocks:staticvariables can be initialized in the same statement where they are declared, in an instance initializer block or in astaticinitializer block. If thestaticvariable is also marked asfinalinstead, it can only be initialized in the same statement of the declaration or in astaticinitializer block, and cannot be initialized more than once.
public class MyClass {
public static int counter = 0; //this is a class (static) variable
public static final int NUMBER = 0; //this is a class (static) final variable
public static final int NUMBER2; //this is a class (static) final variable
public static final int NUMBER3; //this is a class (static) final variable
//This is an instance initializer block
{
counter = 2; //ALLOWED
/*
* DOES NOT COMPILE, static final variables cannot be initialized
* in an instance initializer block
*/
NUMBER2 = 3;
}
//This is a static initializer block
static {
counter = 3; //ALLOWED
NUMBER3 = 5; //ALLOWED
/*
* DOES NOT COMPILE, final variable cannot be initialized
* more than once
*/
NUMBER = 4;
}
}
-
staticmethods: thestatickeyword can be also applied to a method, with the exception ofabstractmethods. This is becauseabstractmethods, by definition, need to be overridden, while,staticmethods cannot be overridden. Thus, the two keywords,staticandabstractare conflicting with each other and cannot be used together.That said, a
staticmethod, as we anticipated, is a method that cannot be overridden by any subclass of the class in which it is defined, but it can only be hidden. I will not discuss here what these two terms, overriding and hiding, mean, because this will be the topics of the next two weeks, so if you are not familiar with these concepts, be patient, please!As for a
staticvariable, astaticmethod can be called without the need of instantiate the class before. This is exactly the reason why themainmethod isstatic. The JVM can call it directly byMyClass.main(), so without creating an instance ofMyClass.
public class MyClass {
public static void saySomething() {
System.out.println("Something");
}
public static void main(String[] args) {
MyClass.saySomething(); //no need to create an instance of the class
new MyClass().saySomething(); //but you can also do that
}
}
-
staticimports: as the standard imports allow you to import classes written by others and use them in your code, thestaticimport allows you to importstaticclass members into your code and use them. Of course, the standard rules for visibility apply, namely if astaticmethod is marked asprivatethere is no way we can access it from another class.Let’s say
MyClassof the previous example is defined in packagemypackage.Aand we want to use itsstaticmethod from another class in another package.
package mypackage.B
import static mypackage.A.MyClass.saySomething;
public class AnotherClass {
public static void main(String[] args) {
/*
* This will work because we have imported it, so we do not
* need to put the name of the class before
*/
saySomething();
/*
* DOES NOT COMPILE, because we are not importing MyClass, so the
* compiler does not know what it is. If we wanted to use that
* we would need to add "import mypackage.A.MyClass"
*/
MyClass.saySomething();
}
}
The naming conventions for static imports are the same as the ones for standard import and the same rules apply for the allowed names (only letters, $, _, . and numbers are allowed; is not possible to start a package name with a number nor a . and a single _ is not allowed).
I hope the discussion on the static keyword was helpful. Next week, as anticipated, we will discuss the concept of method overriding and we will compare that to the one of method overloading!
by Ilenia Salvadori