The curious case of ‘static’ in Java

Consider the following piece of code:

public class Counter {
    private static int count = 0; // Static variable

    public Counter() {
        count++; // Increment count each time a new object is created

    public static int getCount() { // Static method
        return count;

    public static void main(String[] args) {
        Counter c1 = new Counter();
        Counter c2 = new Counter();
        Counter c3 = new Counter();
// Accessing static method
        System.out.println("Total count: " + Counter.getCount()); 

What is going to be the output of this code? If your answer is the following, you are right.

Total count: 3

Now that you have seen static variables in play, you may have a couple of questions, like.

  1. What is a static variable? Where is it used?
  2. Where is this variable stored? How is it different from the normal instance variable?
  3. What are the restrictions on the usage of static variables or static methods?

Why do we need static variables?

Suppose you are a car company. You have to assign an id to every car that is made. Id should ideally be a counter. So, if the company has produced 2000 cars, the 2000th car should have id as 2000.

How are you going to write the code for this?

You would need a variable that stores the total number of cars produced so far. If you make a car class as follows:

public class Car {
    private int numberOfCars = 0; // Instance field to track the number of cars
    private int id; // Instance variable for the car's ID
    private String model; // Instance variable for the car's model
    private String color; // Instance variable for the car's color

//Constructor goes here...

And then, if you create an object of Car like the following:

Car car = new Car();

The numberOfCars variable will have the value of 0 as it is an instance variable.

So, what should we do?

We need something that can hold the value of the number of cars produced and is not part of the Car object. Rather, it should be part of the Car class. So, its value can be increased regardless of whether there is an object or not.

Static variables are exactly for this purpose.

When you declare a variable as static, it means that all the instances of the class share the same variable. In other words, the value of the static variable is common to all objects of that class. For example, if you have a static int count variable in a class, changing its value in one object will affect the value in all other objects of that class.

Here’s the code that demonstrates the usage of static:

public class Car {
    private static int numberOfCars = 0; // Static field to track the number of cars
    private int id; // Instance variable for the car's ID
    private String model; // Instance variable for the car's model
    private String color; // Instance variable for the car's color

    public Car(String model, String color) {
        numberOfCars++; // Increment the number of cars
        id = numberOfCars; // Assign the current count as the car's ID
        this.model = model; // Assign the provided model
        this.color = color; // Assign the provided color

    public int getId() {
        return id;

    public String getModel() {
        return model;

    public String getColor() {
        return color;

    public static int getNumberOfCars() {
        return numberOfCars;

    public static void main(String[] args) {
        Car car1 = new Car("Toyota Camry", "Silver");
        Car car2 = new Car("Honda Civic", "Red");
        Car car3 = new Car("Ford Mustang", "Blue");

        System.out.println("Car 1 ID: " + car1.getId());
        System.out.println("Car 1 Model: " + car1.getModel());
        System.out.println("Car 1 Color: " + car1.getColor());

        System.out.println("Car 2 ID: " + car2.getId());
        System.out.println("Car 2 Model: " + car2.getModel());
        System.out.println("Car 2 Color: " + car2.getColor());

        System.out.println("Car 3 ID: " + car3.getId());
        System.out.println("Car 3 Model: " + car3.getModel());
        System.out.println("Car 3 Color: " + car3.getColor());

        System.out.println("Total number of cars: " + Car.getNumberOfCars());

The output of the code:

Car 1 ID: 1
Car 1 Model: Toyota Camry
Car 1 Color: Silver

Car 2 ID: 2
Car 2 Model: Honda Civic
Car 2 Color: Red

Car 3 ID: 3
Car 3 Model: Ford Mustang
Car 3 Color: Blue

Total number of cars: 3

Where is the static variable stored?

We have 3 segments in Java memory:

  1. Stack Segment — contains local variables and Reference variables (variables that hold the address of an object in the heap).
  2. Heap Segment — contains all created objects in runtime, objects plus their object attributes (instance variables).
  3. Code Segment — the segment where the actual compiled Java bytecodes resides when loaded. Static members (variables or methods) are called class members, meaning they reside where the class (bytecode) resides, which is in the Code Segment.

In Java, static variables are stored in the “static memory” or “class-level memory”. This memory space is associated with the class itself rather than with individual objects (instances) of the class. When a Java program is executed, the static memory is allocated at the start of the program and remains throughout its execution. The static variables are loaded into this memory space when the class is loaded by the Java Virtual Machine (JVM). The exact location of the static memory can vary depending on the JVM implementation and the platform on which the program is running. Generally, the static memory is a part of the JVM’s runtime data area, separate from the stack and heap memory. Since static variables are shared among all instances of a class, they are accessible from any object or method of that class, as well as from other classes, as long as they have the appropriate access level (public, protected, or default). It’s worth noting that static variables persist throughout the entire program execution and retain their values until explicitly modified or the program terminates.

If you want to make projects in Java by investing sometime every day - have a look at 

Static Method

In Java, a static method is a method that belongs to the class itself, rather than to individual instances (objects) of the class. This means that you can call a static method directly on the class itself, without creating an object of the class.

public class MathUtils {
    public static int sum(int a, int b) {
        return a + b;

    public static void main(String[] args) {
        int result = MathUtils.sum(5, 3); // Calling the static method directly on the class
        System.out.println("Sum: " + result);


  • Instance methods can access instance variables and instance methods directly.
  • Instance methods can access class variables and class methods directly.
  • Static methods can access static variables and class methods directly.
  • Static methods cannot access instance variables or instance methods directly—they must use an object reference. Also, class methods cannot use the this keyword as there is no instance for this to refer to.

Static methods in Java cannot directly access instance variables because they are not associated with any specific instance (object) of the class. Instance variables are created and initialized when objects are created, and they hold unique values for each object.

Best Practices

  1. Limited usage: Static variables and methods should be used sparingly and only when necessary. They should be reserved for functionality that is truly shared among all instances of a class or utility functions that don’t rely on instance-specific data. Overuse of static elements can lead to code that is tightly coupled, difficult to test, and lacks flexibility.
  2. Proper encapsulation: Even though static variables and methods can be accessed from anywhere, it’s good practice to limit their accessibility using access modifiers (e.g., private, protected, or package-private) to enforce encapsulation. This ensures that the static elements are only accessed and modified through appropriate methods, providing better control over their usage.
  3. Thread safety: Be cautious when working with shared static variables in a multi-threaded environment. If multiple threads are accessing and modifying the same static variable concurrently, synchronization mechanisms may be required to ensure thread safety. Alternatively, consider using thread-local variables or other strategies to avoid a shared mutable state.
  4. Avoid mutable static variables: It’s generally recommended to avoid mutable static variables as they can lead to unpredictable behaviour and make code harder to reason about. If a static variable needs to be modified, consider using thread-safe data structures or immutable objects to ensure proper concurrency and prevent unintended side effects.
  5. Class variables are referenced by the class name itself, as in Bicycle.numberOfBicycles. This makes it clear that they are class variables.
  6. You can also refer to static fields with an object reference like myBike.numberOfBicycles but this is discouraged because it does not make it clear that they are class variables.


Leave a Reply

Up ↑

%d bloggers like this: