Static Variables and Methods

Static Keyword in Java is used for declaring class variables and method. Static variables and methods belong to class, not to an individual object. A class contains single copy of a class variable across all of its objects.

Static variables and methods are to be referred directly using the class name instead of object’s reference variable, though Java allows to do that.

Class variables and methods are to be referred using the Class name instead of object’s reference variable, though Java allows it.

Syntax:

access_modifier static data_type variable_name;
access_modifier static return_type method_name(arguments) {
// Code
}

Example:

package com.techstackjournal.staticexample;

public class Flight {
	private static int flightCount;

	public Flight() {
		flightCount++;
	}

	public static int getFlightCount() {
		return flightCount;
	}
}
package com.techstackjournal.staticexample;

public class StaticExampleApp {

	public static void main(String[] args) {
		System.out.println("Number of flights on board: " + Flight.getFlightCount());
		new Flight();
		new Flight();
		System.out.println("Number of flights on board: " + Flight.getFlightCount());
		new Flight();
		System.out.println("Number of flights on board: " + Flight.getFlightCount());
	}

}
Number of flights on board: 0
Number of flights on board: 2
Number of flights on board: 3
  • In Flight class, flightCount is declared as static, that means, it is a class variable (not instance variable)
  • We’ve incremented the flightCount in the constructor by one. A static variable is accessible within non-static parts of the class.
  • When an instance of Flight is created, flightCount will be incremented by 1
  • In the main program, we’ve called getFlightCount method directly using class name instead of object’s reference variable
  • The last print statement shows the number of objects as 3, which means flightCount variable is being shared across all 3 objects as they were able to increment it when those objects were being made.

Can Static methods access non-static members of an object?

Static methods cannot access non-static members of an object as non-static members belong to specific objects. When a static method is executing, it may be possible that no objects are created on heap of that class. So, it doesn’t make sense to be able to refer them in static methods. For this reason, Java prevents access on non-static members within static methods.

package com.techstackjournal.staticexample;

public class Flight {
	private static int flightCount;
	private int passengerCount;

	public Flight() {
		flightCount++;
	}
	
	public static int getFlightCount() {
		System.out.println("Current Passenger Count: "+passengerCount);
		return flightCount;
	}
}
package com.techstackjournal.staticexample;

public class StaticExampleApp {

	public static void main(String[] args) {
		System.out.println("Number of flights on board: " + Flight.getFlightCount());
		new Flight();
		System.out.println("Number of flights on board: " + Flight.getFlightCount());
	}

}
Exception in thread "main" java.lang.Error: Unresolved compilation problem: 
	Cannot make a static reference to the non-static field passengerCount

	at com.techstackjournal.staticexample.Flight.getFlightCount(Flight.java:12)
	at com.techstackjournal.staticexample.StaticExampleApp.main(StaticExampleApp.java:6)

When we run above program, we get a compilation error. It clearly states that we cannot make a static reference to the non-static field.

Can static methods be overridden?

Static methods of parent class will not be overridden by subclass even though Java doesn’t throw any compile error. Java treats both of them as two independent methods of both parent and child. So when you call a static method which is present in both base and subclass, always the method of the caller class will be executed.

package com.techstackjournal.staticoverride;

public class Flight {
	public static void display1() {
		System.out.println("This is a flight");
	}

	public void display2() {
		System.out.println("This is a flight");
	}
}
package com.techstackjournal.staticoverride;

public class CharterFlight extends Flight {
	public static void display1() {
		System.out.println("This is a Charter flight");
	}
	public void display2() {
		System.out.println("This is a Charter flight");
	}
}
package com.techstackjournal.staticoverride;

public class StaticExampleApp {

	public static void main(String[] args) {

		Flight flight2 = new CharterFlight();
		flight2.display1();
		flight2.display2();
		new CharterFlight().display1();
		new CharterFlight().display2();
	}

}
This is a flight
This is a Charter flight
This is a Charter flight
This is a Charter flight

Static Initializer

A Static Initializer is a block of code that will be executed once a class is loaded in your program. This block gets executed even before a constructor is executed. Static Initializer need to be written outside of any method or constructor. Similar to static methods, instance variables cannot be accessed within static initializer block.

static {
// Code
}

Static Initializer Example:

package com.techstackjournal.staticinit;

public class StaticBlock {

	static {
		System.out.println("Static block execution completed");
	}

	public StaticBlock() {
		System.out.println("New object created");
	}

}
package com.techstackjournal.staticinit;

public class StaticInitializerApp {

	public static void main(String[] args) {
		new StaticBlock();
		new StaticBlock();
		new StaticBlock();
	}

}
Static block execution completed
New object created
New object created
New object created

You can see that even though we have created 3 objects, the static block is executed only once when the class is loaded even before the constructor.

When to use static variables?

We discussed about instance variables which contain values specific to an object. However, some values can be common across all the objects. Preserving those values in an instance variable doesn’t make sense and it may result in a costly affair due to multiple copies of the same value across all of its objects. In that case, we can go for static keyword to declare a variable.

Also, it is a good practice to declare a variable which has common value and doesn’t change during the application as a static final variable.

public class Constants {
    public static final String SITE_NAME = "Tech Stack Journal";
}

When to use static methods?

If there are no instance variables in a class and all it has some utility methods, it doesn’t make sense to create an object for it as those objects do not have any state. In that situation, we can declare all those methods as static, so that we can access those utility methods directly by using the class name.

For example, in the below example, Calculator class doesn’t have any instance variables, and all we have are some utility methods. So we declared all of them as static. Also we want to prevent the user from creating instance of the class, so we declared a private constructor. Since private constructor is not accessible outside of the class, user will not be able to create an instance of it.

package com.techstackjournal.calc;

public class Calculator {

	private Calculator() {
	}

	public static double add(double n1, double n2) {
		return n1 + n2;
	}

	public static double subtract(double n1, double n2) {
		return n1 - n2;
	}

	public static double multiply(double n1, double n2) {
		return n1 * n2;
	}

	public static double divide(double n1, double n2) {
		return n1 / n2;
	}

	public static double modulus(double n1, double n2) {
		return n1 % n2;
	}
}
package com.techstackjournal.calc;

public class CalculatorApp {

	public static void main(String[] args) {
		double n1 = 6, n2 = 3;

		System.out.println("Addition: " + Calculator.add(n1, n2));
		System.out.println("Subtraction: " + Calculator.subtract(n1, n2));
		System.out.println("Multiplication: " + Calculator.multiply(n1, n2));
		System.out.println("Division: " + Calculator.divide(n1, n2));
		System.out.println("Modulus: " + Calculator.modulus(n1, n2));

	}

}
Addition: 9.0
Subtraction: 3.0
Multiplication: 18.0
Division: 2.0
Modulus: 0.0