Insights into Company
← Java

Static Keyword

Understand the idea. Compare it. Explain it. Test yourself.

Question 1 of 10

What is the static keyword?

Solution and explanation

What it is

static marks a member as belonging to the class itself rather than to individual objects. There is one copy shared by all instances, and it can be used without creating an object.

Where static can be used

UsageMeaning
Static variableOne shared copy for the class
Static methodCalled on the class; no this
Static blockRuns once when the class is initialised
Static nested classNested class that does not need an outer instance
Static importUse static members without the class name (import static java.lang.Math.*;)

Example

public class Order {
    private static int totalOrders = 0;                 // shared counter
    private static final double GST = 0.18;             // shared constant
    private final int orderNo;

    static { System.out.println("Order class loaded"); }   // static block

    public Order() { orderNo = ++totalOrders; }

    public static int getTotalOrders() { return totalOrders; }    // static method
    public static double withGst(double amount) { return amount * (1 + GST); }
}

new Order(); new Order();
System.out.println(Order.getTotalOrders());   // 2
System.out.println(Order.withGst(1000));      // 1180.0

Rules

  • Static methods cannot use this or super and cannot access instance members directly.
  • Static methods are not overridden (they are hidden).
  • Top-level classes cannot be static; only nested classes can.
  • Local variables cannot be static.

When to use

Constants, counters, utility/helper functions (Math.sqrt, Collections.sort), factory methods (List.of). Avoid mutable static state in multi-threaded or testable code: it is effectively a global variable.

Practice explaining this
Question 2 of 10

What is a static variable?

Solution and explanation

What it is

A static variable (class variable) is declared with static. Only one copy exists per class (per class loader), shared by every object, created when the class is initialised.

public class Visitor {
    static int count = 0;          // shared
    String name;                   // per object

    Visitor(String name) {
        this.name = name;
        count++;
    }
}

new Visitor("A"); new Visitor("B"); new Visitor("C");
System.out.println(Visitor.count);   // 3
Class area: Visitor.count = 3
Heap: Visitor{name="A"}  Visitor{name="B"}  Visitor{name="C"}

Characteristics

  • Initialised once, when the class is first used; default values apply (0, null, false).
  • Lives as long as the class is loaded, usually the whole application.
  • Accessed with the class name: Visitor.count (accessing via an object compiles but is misleading).
  • Stored with the class's data (in the heap alongside the Class object since Java 8; metadata in Metaspace).

Constants

public static final int MAX_LOGIN_ATTEMPTS = 3;     // UPPER_SNAKE_CASE by convention

Thread safety

count++ is not atomic: two threads can read the same value and lose an update. Use AtomicInteger or synchronisation:

private static final AtomicInteger count = new AtomicInteger();
count.incrementAndGet();

Pitfalls

  • Static collections that keep growing cause memory leaks.
  • Static mutable state makes unit tests depend on each other.
Practice explaining this
Question 3 of 10

What is a static method?

Solution and explanation

What it is

A static method belongs to the class and is called without an object: ClassName.method(). It has no this reference, so it works only with its parameters and static data.

public final class SalaryUtils {
    private SalaryUtils() { }

    public static double monthlyInHand(double ctcLpa, double pfPercent) {
        double monthly = ctcLpa * 100000 / 12;
        return monthly - monthly * pfPercent / 100;
    }
}

double inHand = SalaryUtils.monthlyInHand(12, 6);   // no object needed

Examples from the JDK

Math.max(), Integer.parseInt(), String.valueOf(), Arrays.sort(), Collections.unmodifiableList(), List.of(), LocalDate.now().

Why is main static?

The JVM must call main before any object exists, so it must be static.

Rules

  • Can access static variables and call other static methods directly.
  • Cannot access instance variables or instance methods directly (needs an object reference).
  • Cannot use this or super.
  • Can be overloaded; cannot be overridden (a same-signature static method in a subclass hides it).
  • Can be called through an object reference, but it still uses the declared type, which is confusing.

When to use

  • Pure functions that depend only on inputs (calculations, validation, formatting).
  • Factory methods (Money.ofRupees(500)).
  • Utility classes.

Avoid static methods for business logic that needs collaborators (repositories, services); those are hard to mock in tests. Prefer instance methods on injected beans.

Practice explaining this
Question 4 of 10

Can a static method access instance data directly?

Solution and explanation

Answer

No. A static method runs without any object, so there is no this to say whose instance variable is meant. Accessing an instance field or method directly is a compile error.

public class Student {
    private String name = "Asha";              // instance variable
    private static String school = "DPS";     // static variable

    public static void print() {
        System.out.println(school);           // OK: static
        // System.out.println(name);          // error: non-static variable name cannot be referenced from a static context
        // display();                         // error: non-static method
    }

    public void display() { System.out.println(name); }
}

The way around: use an object reference

public static void print(Student s) {
    System.out.println(s.name);               // OK: accessed through a reference
    s.display();
}

public static void main(String[] args) {
    Student s = new Student();                // main is static, so create an object first
    s.display();
}

The reverse is fine

Instance methods can access static members directly, because static data does not depend on any particular object.

From \ ToStatic memberInstance member
Static methodDirectlyOnly via an object reference
Instance methodDirectlyDirectly (this is implicit)
Practice explaining this
Question 5 of 10

Can a static method be overridden?

Solution and explanation

Answer

No. Static methods are bound at compile time to the declared (reference) type, not the runtime object type. If a subclass declares a static method with the same signature, it hides the parent's method; it does not override it.

class Parent {
    static void greet() { System.out.println("Parent static"); }
    void show()         { System.out.println("Parent instance"); }
}

class Child extends Parent {
    static void greet() { System.out.println("Child static"); }     // hides Parent.greet()
    @Override void show() { System.out.println("Child instance"); } // overrides
}

Parent p = new Child();
p.greet();    // Parent static   ← decided by reference type (compile time)
p.show();     // Child instance  ← decided by object type (run time)

Proof

Adding @Override to Child.greet() gives a compile error: "method does not override or implement a method from a supertype".

Related rules

  • A static method cannot hide an instance method, and an instance method cannot override a static one (compile errors).
  • The hiding method must not have weaker access.
  • Overriding = runtime polymorphism; hiding = compile-time resolution.

Why the design

Overriding relies on the actual object, but static methods do not need an object at all, so there is nothing to choose from at run time.

Practice explaining this
Question 6 of 10

What is method hiding?

Solution and explanation

What it is

Method hiding happens when a subclass defines a static method with the same signature as a static method in its parent. The subclass method hides the parent one. Which method runs depends on the reference type used at compile time, not on the actual object.

class Logger {
    static String level() { return "INFO"; }
}

class DebugLogger extends Logger {
    static String level() { return "DEBUG"; }    // hides Logger.level()
}

Logger a = new DebugLogger();
DebugLogger b = new DebugLogger();

System.out.println(a.level());            // INFO   (reference type Logger)
System.out.println(b.level());            // DEBUG  (reference type DebugLogger)
System.out.println(Logger.level());       // INFO
System.out.println(DebugLogger.level());  // DEBUG

Hiding vs overriding

Method hidingMethod overriding
Methods involvedStaticInstance
ResolvedCompile time, by reference typeRun time, by object type
PolymorphismNoYes
@Override allowedNoYes

Field hiding

Fields are never overridden either: a subclass field with the same name hides the parent field, and access is resolved by reference type.

class A { String name = "A"; }
class B extends A { String name = "B"; }
A obj = new B();
System.out.println(obj.name);   // A

Tip: always call static methods with the class name (DebugLogger.level()) to avoid confusion.

Practice explaining this
Question 7 of 10

Can a static method be overloaded?

Solution and explanation

Answer

Yes. Overloading only requires the same method name with different parameter lists, and that works for static methods just as for instance methods. The compiler picks the version from the argument types.

public final class Calculator {
    public static int add(int a, int b)            { return a + b; }
    public static double add(double a, double b)   { return a + b; }
    public static int add(int a, int b, int c)     { return a + b + c; }
    public static int add(int... numbers)          { return Arrays.stream(numbers).sum(); }
}

Calculator.add(2, 3);          // int version
Calculator.add(2.5, 3.1);      // double version
Calculator.add(1, 2, 3);       // three-arg version
Calculator.add(1, 2, 3, 4);    // varargs

Even main can be overloaded

public static void main(String[] args) { main(5); }
public static void main(int times) { System.out.println("Overloaded main " + times); }

The JVM only calls main(String[]) as the entry point.

Rules

  • Changing only the return type is not overloading (compile error).
  • A static and an instance method cannot share the same signature, but they can be overloads with different parameters.
  • JDK examples: String.valueOf(int), String.valueOf(double), String.valueOf(char[]); Math.abs(int/long/float/double).
Practice explaining this
Question 8 of 10

What is a static block?

Solution and explanation

What it is

A static block (static initializer) is a block of code marked static { } inside a class. It runs once, when the class is initialised, before any object is created or static method is called. It is used for complex initialisation of static fields.

public class StateCodes {
    private static final Map<String, String> CODES;

    static {
        Map<String, String> m = new HashMap<>();
        m.put("HR", "Haryana");
        m.put("KA", "Karnataka");
        m.put("MH", "Maharashtra");
        CODES = Collections.unmodifiableMap(m);
        System.out.println("State codes loaded");
    }

    public static String name(String code) { return CODES.getOrDefault(code, "Unknown"); }
}

System.out.println(StateCodes.name("HR"));
State codes loaded
Haryana

Characteristics

  • A class can have several static blocks; they run in source order, together with static field initializers.
  • Can only access static members directly.
  • Cannot throw checked exceptions; wrap them (an exception here causes ExceptionInInitializerError, and later uses throw NoClassDefFoundError).
  • Classic use: loading a JDBC driver (static { Class.forName("com.mysql.cj.jdbc.Driver"); }), loading native libraries (System.loadLibrary), building lookup tables.

Static block vs instance block vs constructor

Static blockInstance blockConstructor
RunsOnce per classEvery object, before the constructor bodyEvery object
AccessesStatic membersEverythingEverything
Practice explaining this
Question 9 of 10

When is a static block executed?

Solution and explanation

Answer

When the class is initialised, which happens once, on the first active use of the class:

  • creating the first object (new Order()),
  • calling a static method,
  • reading or writing a static field that is not a compile-time constant,
  • Class.forName("com.app.Order"),
  • initialising a subclass (the parent is initialised first),
  • the class containing main when the program starts.

It does not run when you:

  • only declare a variable of that type (Order o;),
  • access a compile-time constant (static final int MAX = 10; is inlined by the compiler),
  • create an array of that type (new Order[10]),
  • use Order.class.

Order of execution

class Parent {
    static { System.out.println("1. Parent static"); }
    { System.out.println("3. Parent instance block"); }
    Parent() { System.out.println("4. Parent constructor"); }
}

class Child extends Parent {
    static { System.out.println("2. Child static"); }
    { System.out.println("5. Child instance block"); }
    Child() { System.out.println("6. Child constructor"); }
}

public class Main {
    static { System.out.println("0. Main static (before main runs)"); }
    public static void main(String[] args) {
        new Child();
        new Child();   // static blocks do not run again
    }
}
0. Main static (before main runs)
1. Parent static
2. Child static
3. Parent instance block
4. Parent constructor
5. Child instance block
6. Child constructor
3. Parent instance block
4. Parent constructor
5. Child instance block
6. Child constructor

Class initialisation is thread-safe: the JVM guarantees a static block runs exactly once even if many threads use the class at the same time.

Practice explaining this
Question 10 of 10

What is a static nested class?

Solution and explanation

What it is

A static nested class is a class declared static inside another class. It is associated with the outer class, not with an outer object, so it can be created without an instance of the outer class.

public class Pizza {
    private final String size;
    private final List<String> toppings;

    private Pizza(Builder b) { this.size = b.size; this.toppings = b.toppings; }

    public static class Builder {                 // static nested class
        private String size = "Medium";
        private final List<String> toppings = new ArrayList<>();

        public Builder size(String size) { this.size = size; return this; }
        public Builder topping(String t) { toppings.add(t); return this; }
        public Pizza build() { return new Pizza(this); }   // can call Pizza's private constructor
    }
}

Pizza p = new Pizza.Builder().size("Large").topping("Paneer").topping("Olives").build();

Characteristics

  • Can access the outer class's static members directly, including private ones.
  • Cannot access the outer class's instance members without an object reference.
  • Does not hold a hidden reference to an outer object, so it uses less memory and avoids leaks.
  • Can have any access modifier.

Static nested vs inner class

Static nestedInner (non-static)
Needs outer objectNo: new Outer.Nested()Yes: outer.new Inner()
Access to outer instance fieldsNo (only via a reference)Yes
Hidden outer referenceNoYes

Real examples

Map.Entry, AbstractMap.SimpleEntry, builders, and node classes of linked lists and trees (static class Node<T>).

Guideline from Effective Java: if a nested class does not need access to an outer instance, make it static.

Practice explaining this