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.
static
fields: when you mark a variable asstatic
you 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!
static
initializer blocks:static
variables can be initialized in the same statement where they are declared, in an instance initializer block or in astatic
initializer block. If thestatic
variable is also marked asfinal
instead, it can only be initialized in the same statement of the declaration or in astatic
initializer 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;
}
}
-
static
methods: thestatic
keyword can be also applied to a method, with the exception ofabstract
methods. This is becauseabstract
methods, by definition, need to be overridden, while,static
methods cannot be overridden. Thus, the two keywords,static
andabstract
are conflicting with each other and cannot be used together.That said, a
static
method, 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
static
variable, astatic
method can be called without the need of instantiate the class before. This is exactly the reason why themain
method 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
}
}
-
static
imports: as the standard imports allow you to import classes written by others and use them in your code, thestatic
import allows you to importstatic
class members into your code and use them. Of course, the standard rules for visibility apply, namely if astatic
method is marked asprivate
there is no way we can access it from another class.Let’s say
MyClass
of the previous example is defined in packagemypackage.A
and we want to use itsstatic
method 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