Java is an object oriented language. This means you need to create an instance or object of a class in order for it to be useful. When we create an object in Java, we create a copy of its variables such that each object has its own copy.
public class Car {
public String color;
}
// ...
Car car1 = new Car();
car1.color = "red";
Car car2 = new Car();
car2.color = "blue";
car1.color // red
car2.color //blue
When we declare a variable or method as static, the variable or method belongs to the class and is created as soon as the class is loaded in memory (as opposed to object creation.) All instances of the class will share (or see) the same variable. Static variables are also known as class variables. The static
keyword can be used with variables, methods, blocks and nested classes.
To access static variables or methods, we don’t need to create an object of the class since they belong to the class itself.
public class Foo {
public static void staticMethod() {
// do something
}
}
You can call the staticMethod()
without creating an instance of the Foo
class.
Foo foo = new Foo();
// Call static method using the instance (works but un-necessary)
foo.staticMethod()
// Or you can call the static method directly
Foo.staticMethod()
If you declare a static variable in your class, all instance of the same class will see one value because static variables (and methods) belong to the class and are shared between instances.
class Foo {
public static int staticNum = 1;
}
If one instance changes the value of the static field, all instances will see the change.
Foo foo1 = new Foo();
foo1.staticNum = 2;
Foo foo2 = new Foo();
System.out.println(foo2.staticNum); // prints 2
Static blocks
If you need to initialize static fields, you can use static blocks. The static block is run once when the class is loaded into memory and is typically used for static fields initialization.
class Foo {
public static List<Integer> numbers = new ArrayList<>();
// static block
static {
numbers.add(1);
numbers.add(2);
numbers.add(3);
}
}
Static classes
A class can be marked as static only if it is a nested class. Static inner classes don’t require a reference of its enclosing class and can be accessed directly. Due to their nature, static classes cannot access non-static members of its enclosing class.
public class StaticNestedExample {
private static String name = "outer class"
//Static class
static class StaticClass {
// non-static method
public void print(){
System.out.println(str);
}
}
}
// ..
StaticNestedExample.StaticClass o = new StaticNestedExample.StaticClass();
o.print() // prints "outer class"
Are static variables garbage collected?
The answer is no. Static variables are not garbage collected since they belong to the class (unless the class loader itself is garbage collected such is when web apps are unloaded.)
Use cases
In practice, static
keyword is mostly used for defining constants and for static factory methods. Static methods are also used to create the Singleton design pattern in Java. Many utility classes like java.lang.Math
exposes all their methods as static. Many conversion methods like valueOf()
are also static.
While static methods are great, they make unit testing difficult. If you have a method that is calling a static method to do something (e.g. read from the database,) it’s harder to mock the static method to return a mocked response. This is my biggest gripe with static methods. Although you could do it with tools like PowerMockito. I use static keyword for defining constants, static factory methods and sometimes simple value conversion methods. So, how do you use static methods in your code or have any tips that you want to share with others? Just leave a comment below.