Topic 48 of 119 5. Methods in Java Interactive Tutorial

Static Methods in Java: Class-Level Behavior and Usage

14 mins read Last updated: 22 Aug 2026 26,418 views

Direct Answer & Core Concept

A static method belongs to the class rather than to any object of it. You call it through the class name, with no object in sight: Math.sqrt(16) and Math.max(a, b) are the everyday examples. Instance methods, by contrast, need an object, because they operate on the state of one particular object. That single difference explains almost everything else about them. A static method has no this reference, because there is no particular instance for this to point at. It cannot read an instance field, call an instance method, or use super, because all three are ways of saying "this particular object." If you find yourself wanting any of those inside a static method, what you actually want is a parameter, and the method is probably better as an instance method anyway. The second thing to understand is that static methods are not inherited the way instance methods are. A subclass may declare a static method with the same signature, and it will compile, but the call is resolved at compile time by the type of the reference. This is called method hiding, and it behaves nothing like overriding, where the runtime type of the object decides. That distinction is the usual source of confusion, so it gets its own section below. Static methods also have a memory consequence worth knowing. They live on the class itself rather than per object, so a thousand objects of one class share one copy of each static method. That makes them a natural fit for stateless helpers, pure calculations, factory methods, and constants declared static final as described in constants.

Detailed Explanation & Mechanics

1) Calling a Static Method

The class name is the receiver. No object is created and none is needed.

Main.java
Run Online
public class MathUtils {
    public static int square(int value) {
        return value * value;
    } public static void main(String[] args) {
        // Called through the class name
        int result = MathUtils.square(SIX);
        System.out.println(result);
    }
}

Because there is no object, there is also no way to reach one. Attempting to use this inside a static method is a compile error, and so is touching an instance field.


Diagram comparing a static method reached through the class name with an instance method reached through an object reference
A static method is invoked through the class. An instance method needs an object, because it acts on that object state.

2) Why this and super Are Unavailable

Both keywords answer a question about which object, and a static method has no object to point at. The compiler rejects the attempt rather than passing some default, because any guess would be wrong.

Main.java
Run Online
public class Report {
    private String owner;
    // NOT ALLOWED: no object exists in a static method
    // public void send() {
    //     System.out.println(owner);     // cannot read an instance field
    //     this.owner = "x";              // no this reference exists
    //     helper();                      // helper must be static too
    // }
}

The way out is to pass the object in as a parameter, which converts the problem back into an ordinary instance method. If a method needs object state, it should just be an instance method.

You want toIn a static methodIn an instance method
Read a fieldOnly if the field is also staticthis.field
Call another methodOnly if that method is staticAny method, static or not
Reach a superclass memberNot possiblesuper.method()
Access object statePass it as a parameterAvailable directly

3) Static Fields Share, Instance Fields Do Not

Every instance field has its own copy per object. A static field has exactly one copy on the class, shared by everything that uses it.

Main.java
Run Online
public class Counter {
    private static int totalCreated = 0;
    // one copy, on the class
    private int instanceCount = 0;
    // a copy per object
    public Counter() {
        totalCreated = totalCreated + 1;
    } public static int getTotalCreated() {
        return totalCreated;
    }
}

Creating five Counter objects leaves totalCreated at five while each object keeps its own instanceCount. This is what makes static state shared mutable state, which is precisely why it needs care under concurrency.

A static field that every object mutates is a shared bottleneck across threads. totalCreated = totalCreated + 1 is not atomic, so two threads can lose an increment. Use an atomic wrapper or a lock if this is real.


Diagram showing one shared static area on the class beside several objects each holding their own instance fields
One static copy lives on the class. Every object carries its own instance fields, which is why state can diverge between them.

4) Method Hiding Is Not Overriding

This is the distinction that catches experienced developers too, so it is worth being precise about. An instance method can be overridden, and the runtime type of the object selects the implementation. A static method can only be hidden, and the compiler selects using the declared type of the reference at the point of the call.

Main.java
Run Online
public class Base {
    public static void describe() {
        System.out.println("base");
    }
}public class Derived extends Base {
    public static void describe() {
        // legal, this is hiding
        System.out.println("derived");
    }
}public class Main {
    public static void main(String[] args) {
        Base reference = new Derived();
        reference.describe();
        // prints base, not derived
        Derived.describe();
        // prints derived
    }
}

The variable holds a Derived object, yet the call prints base. Dynamic dispatch never happens for static methods because there is no object being dispatched on; the compiler already decided from the reference type. This is exactly the opposite of dynamic method dispatch.

BehaviourInstance methodStatic method
Redefined in a subclassOverriddenHidden
Chosen byRuntime type of the objectDeclared type of the reference
Resolved whenAt runtimeAt compile time
Uses @OverrideYes, and the compiler checks itNo, and the compiler rejects it
Needs an objectYesNo

Writing @Override on a hidden static method is a compile error. The annotation exists precisely to catch an accidental static declaration that was meant to override.

5) main Is Static, and Why

The entry point every Java program starts from is static, for a practical reason: the JVM must be able to launch it before any object of your class exists.

Main.java
Run Online
public static void main(String[] args) {
    // args holds the command line values
    System.out.println(args.length);
}

There is nothing to construct the class from, so the class itself is the only thing available to call it on. This is also why you can call a static method from anywhere without an instance, and why a main method in any class in a project can serve as the program entry point.


Timeline from class loading to metaspace placement to static field initialization to the main method running
The JVM loads and initializes the class, which is when static fields are assigned, and only then does it call main.

6) Utility Classes and Their Constructor

A class that exists only to hold static helpers should not be instantiable. Marking the constructor private enforces that at compile time, and is what the standard library does for Math and Collections.

Main.java
Run Online
public final class StringUtils {
    // Prevent anyone from creating an instance of a utility class
    private StringUtils() {
        throw new UnsupportedOperationException("utility class");
    } public static boolean isBlank(String value) {
        return value == null || value.trim().isEmpty();
    }
}StringUtils.isBlank(null);
// works
// new StringUtils();       // compile error, constructor is private

The final keyword matters as well. A utility class with no reason to be subclassed should be final, which stops a subclass from being created. That also prevents the static hiding problem in the previous section from arising here, since nothing can extend the class. Both practices are covered under the final keyword.

7) Static Factory Methods

One of the most valuable uses of a static method is a factory, because it gives a call site a meaningful name and lets the method decide which concrete type to return.

Main.java
Run Online
public class Money {
    private final long amountInCents;
    private Money(long amountInCents) {
        this.amountInCents = amountInCents;
    } // Named factories, clearer than a bare constructor
    public static Money ofCents(long cents) {
        return new Money(cents);
    } private static final long NO_CENTS = 0L;
    public static Money zero() {
        return new Money(NO_CENTS);
    }
}

Compared with a plain constructor, a factory can return a cached instance, an existing instance, or a subtype. It is also the idiomatic way to hide a private constructor, which is the pattern behind List.of() and the immutable types described in records.

8) When to Use Static, and When Not To

Static is the right choice when the operation is genuinely stateless, when it is a calculation, a parser, a factory, or a constant accessor. The test is simple: would this method give a sensible answer if it had no idea which object called it? If yes, static fits.

Avoid it when the method reads or writes instance state, because you cannot reach that state and forcing it through parameters undoes the object model.


Comparison of a good static utility method with a bad static method that secretly depends on instance state
Static suits pure functions and factories. If the method needs object state, make it an instance method.

SituationRecommended
Pure calculation, no stateStatic, safe and cheap
Factory returning an instanceStatic, hides the constructor
Reads instance fieldsInstance method
Mutable state shared across objectsAvoid, or pass it in as a parameter
Utility classStatic, with a private constructor and final
Meant to vary per subclassInstance method, so overriding works
Hides an instance in a static fieldAvoid, it breaks with multiple instances

9) Common Mistakes

MistakeSymptomFix
Using this in a static methodCompile errorPass the object in as a parameter.
Reading an instance fieldCompile errorMake it an instance method.
@Override on a static methodCompile errorRemove it, hiding is not overriding.
Expecting a static call to be polymorphicThe base version runsMake the method an instance method.
Storing an instance in a static fieldShared state across objectsKeep it per instance.
Incrementing a static counter unsafelyLost updates under threadsUse an atomic wrapper or a lock.
Utility class with a public constructorPointless instancesMake the constructor private, class final.
Static method that really is per-objectAwkward parametersReconsider as an instance method.


Infographic of eight common Java static method mistakes with symptoms and corrections
Eight static method mistakes. The first four are compile errors, so they never reach production.

Frequently Asked Questions

What is a static method in Java?


A method that belongs to the class rather than to any object of it. It is invoked through the class name, such as Math.sqrt, and needs no instance to exist. Because there is no particular object involved, it has no this reference and cannot touch instance fields or call instance methods directly.

Can we override a static method in Java?


No. A subclass may declare a static method with the same signature, and the compiler allows it, but this is method hiding rather than overriding. Selection happens at compile time using the declared type of the reference, not the runtime type of the object, so writing @Override on such a method is a compile error.

Why can a static method not use the this keyword?


Because this names a particular object, and a static method has no object to name. It is invoked on the class, so there is nothing for this to refer to. The same reasoning applies to super and to instance fields. If you need object state, pass the object in as a parameter or make the method an instance method.

Can a static method call another non-static method?


Not directly, and trying is a compile error. It may only call static methods and access static fields, since both belong to the class. A common workaround is to pass the needed object in as a parameter, but if the method needs instance state at all it is usually better written as an instance method.

Are static methods inherited?


They are available to subclasses, but they are not inherited in the sense that matters. A subclass can redeclare one to hide it, and the compiler then picks using the declared type of the reference at the call site. Unlike an overridden instance method, no runtime type check or dynamic dispatch is involved.

Why should a utility class have a private constructor?


To make instantiation impossible at compile time, which signals that the class is meant to be used through its static methods alone. Making the class final as well prevents subclassing, which would otherwise allow a subclass to hide the static methods and reintroduce the surprising selection behaviour described earlier.

What is a static factory method and why use one?


A static method that creates and returns an instance. It is more readable than a bare constructor at the call site, it can hide a private constructor, it can return a cached instance to avoid repeated allocation, and it is free to return a subtype of the declared class.

Can a static method be used to store state?


It can, but you should think carefully first. A static field is shared by every instance and by every thread, so mutating it is a concurrency hazard, since a simple increment is not atomic. Shared immutable constants are fine, and an atomic wrapper or a lock makes shared counters safe, but per-object state has no business in a static field.

Runnable Code Example: Static Methods in Java

Java 17+
Main.java
Run Online
// Demonstrates static methods, static fields, and method hiding.
public class StaticMethodDemo {
    // A constant is a static final field, not a static method,
    // but it is created at class initialisation time like one.
    public static final String APP_VERSION = "2.5.0";
    // One copy on the class, shared by every instance.
    private static int instancesCreated = 0;
    // Per instance state, which a static method cannot reach.
    private final String label;
    public StaticMethodDemo(String label) {
        this.label = label;
        instancesCreated = instancesCreated + 1;
    } // STATIC UTILITY: no object involved, called through the class
    public static String banner(String text) {
        return "[v" + APP_VERSION + "] " + text;
    } // Reads only static state, so it can be static
    public static int getInstancesCreated() {
        return instancesCreated;
    } // Needs instance state, so it must be an instance method.
    // Removing static from this method and reading label compiles fine;
    // keeping it static and reading label is a compile error.
    public String describe() {
        return label + " (" + APP_VERSION + ")";
    } // STATIC FACTORY: gives the call site a meaningful name
    public static StaticMethodDemo named(String label) {
        return new StaticMethodDemo(label);
    } // UTILITY CLASS: private constructor stops instantiation at compile time
    public static final class Suffixes {
        private Suffixes() {
            throw new UnsupportedOperationException("utility class");
        } public static String withSuffix(String value, String suffix) {
            return value + suffix;
        }
    } // METHOD HIDING: not overriding, selection is at compile time
    public static String kind() {
        return "base";
    } public static class Extended extends StaticMethodDemo {
        public Extended(String label) {
            super(label);
        } // Legal, but this hides rather than overrides
        public static String kind() {
            return "extended";
        }
    } public static void main(String[] args) {
        // STATIC CALLS THROUGH THE CLASS NAME, NO OBJECT NEEDED
        System.out.println(banner("starting up"));
        System.out.println("version constant: " + APP_VERSION);
        // STATIC FACTORY INSTEAD OF new
        StaticMethodDemo first = StaticMethodDemo.named("orders");
        StaticMethodDemo second = StaticMethodDemo.named("invoices");
        System.out.println("instances created: " + getInstancesCreated());
        // INSTANCE CALLS, THESE NEED AN OBJECT
        System.out.println(first.describe());
        System.out.println(second.describe());
        // THE UTILITY NESTED CLASS
        System.out.println(Suffixes.withSuffix("report", ".csv"));
        // new Suffixes();   // compile error, the constructor is private
        // METHOD HIDING: the reference type decides, not the object
        StaticMethodDemo reference = new Extended("child");
        System.out.println("via base reference:  " + reference.kind());
        System.out.println("via extended type:  " + Extended.kind());
        // THESE ARE ALL COMPILE ERRORS AND ARE SHOWN AS COMMENTS
        //
        // this inside a static method: no object to refer to
        // public void bad() {
        //     System.out.println(this.label);
        // }
        //
        // calling an instance method from a static one
        // public static void alsoBad() {
        //     StaticMethodDemo demo = new StaticMethodDemo("x");
        //     demo.describe();            // not allowed from here
        // }
        //
        // @Override on a hidden static method
        // @Override
        // public static String kind() { return "x"; }
    }
}/*
    ACTUAL OUTPUT:

        [v2.5.0] starting up
        version constant: 2.5.0
        instances created: 2
        orders (2.5.0)
        invoices (2.5.0)
        report.csv
        via base reference:  base
        via extended type:  extended

    THE SEVEN THINGS TO REMEMBER
    1) A STATIC METHOD BELONGS TO THE CLASS, so it is called through the
       class name and needs no object.
    2) NO this, NO super, NO INSTANCE STATE. The compiler rejects all
       three, because each one asks which object is meant and a static
       method has no object.
    3) ONLY STATIC CALLS STATIC. A static method may use other static
       methods and static fields, and nothing else directly.
    4) STATIC IS NOT OVERRIDING. A subclass can declare a method with the
       same signature, but the compiler picks using the declared type of
       the reference, so reference.kind() above prints base even though
       the object is an Extended. This is method hiding.
    5) @Override ON A STATIC METHOD IS A COMPILE ERROR, which is the
       annotation doing its job of catching a mistaken static keyword.
    6) ONE COPY, SHARED. A static field is stored on the class, so every
       object of that class reads and writes the same value. Mutable
       shared state is a concurrency hazard, since += is not atomic.
    7) GIVE UTILITY CLASSES A PRIVATE CONSTRUCTOR AND MAKE THEM final, so
       nobody can create a pointless instance or hide the methods.
*/

Common Java Technical Interview Questions & Answers

Interview Prep
Q1: What distinguishes a static method from an instance method in Java?\nA1: A static method belongs to the class and is invoked through the class name, while an instance method belongs to an object and operates on that object state. A static method has no this reference, cannot read instance fields, and cannot call instance methods directly, since all of those require a specific object.\nQ2: Can a static method be overridden in a subclass?\nA2: No. A subclass may declare a static method with the same signature, and the compiler accepts it, but this is method hiding rather than overriding. Selection happens at compile time using the declared type of the reference, so writing @Override on such a method is a compile error.\nQ3: Why can a static method not use the this or super keywords?\nA3: Both keywords identify a particular object, and a static method is invoked on the class so there is no object for them to name. The compiler rejects the attempt outright. If object state is needed, pass the object in as a parameter or write the method as an instance method instead.\nQ4: What can a static method call and access?\nA4: Only other static methods and static fields, since both belong to the class. Calling an instance method or reading an instance field from static context is a compile error. This restriction is what keeps static code free of hidden object dependencies.\nQ5: Are static methods inherited by subclasses?\nA5: They are usable from subclasses but are not inherited in a way that affects behaviour. A subclass can redeclare one to hide it, and the compiler then selects using the declared type of the reference at the call site. Unlike an overridden instance method, no runtime type check or dynamic dispatch takes place.\nQ6: Why should a utility class have a private constructor and be final?\nA6: A private constructor makes instantiation impossible at compile time, signalling that the class is used only through its static methods. Declaring the class final prevents subclassing, which would otherwise let a subclass hide the static methods and reintroduce the surprising compile-time selection behaviour.\nQ7: What are static factory methods useful for?\nA7: They create instances under a name that describes the intent, which reads better than a bare constructor. They can hide a private constructor, return a cached instance to avoid repeated allocation, and return a subtype of the declared return type, none of which a plain constructor can express.\nQ8: Is it safe to keep mutable state in a static field?\nA8: Generally not without care, since a static field is shared by every instance and every thread. A simple increment is not atomic, so concurrent updates can lose changes. Shared immutable constants such as static final are safe, and an atomic wrapper or a lock makes counters safe, but genuinely per-object state belongs in an instance field.

Key Takeaways, Best Practices & Clean Code Rules

Java Best Practice & Production Rules

Make a method static only when it is stateless, since needing instance state usually means it should be an instance method.\nInvoke static methods through the class name, which makes it obvious at the call site that no object is involved.\nPass an object in as a parameter rather than reaching for a static field, which keeps the dependency visible and avoids shared mutable state.\nGive utility classes a private constructor and declare them final, so they cannot be instantiated or subclassed.\nPrefer static final for true constants, and treat any mutable static field as shared state that needs thread safety.\nNever use this or super in a static method, and pass the required object in instead of trying to reach an instance.\nDo not expect a static method to be polymorphic; if behaviour must vary per subclass, declare it as an instance method so overriding applies.\nUse static factory methods for creation when they improve readability, hide a constructor, or can return a cached or subtype instance.\nKeep static initialisation cheap, since it runs once at class load and a slow or failing initialiser blocks every use of the class.\nAvoid storing objects in static fields, because a single shared instance conflicts with any code expecting independent objects.\nIncrement a shared static counter with an atomic wrapper or a lock rather than a plain assignment, which is not thread safe.\nPrefer interfaces with static methods over utility classes when no state is needed, since a final utility class cannot be substituted in tests.
We value your privacy & transparency

OperateTools uses cookies and local storage to ensure basic tool functionality, preserve preferences, and analyze aggregated traffic. We never sell your personal data or index your document files. Learn more in our Privacy Policy.