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.
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.
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.
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 to
In a static method
In an instance method
Read a field
Only if the field is also static
this.field
Call another method
Only if that method is static
Any method, static or not
Reach a superclass member
Not possible
super.method()
Access object state
Pass it as a parameter
Available 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.
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.
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.
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.
Behaviour
Instance method
Static method
Redefined in a subclass
Overridden
Hidden
Chosen by
Runtime type of the object
Declared type of the reference
Resolved when
At runtime
At compile time
Uses @Override
Yes, and the compiler checks it
No, and the compiler rejects it
Needs an object
Yes
No
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.
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.
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.
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.
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.
Static suits pure functions and factories. If the method needs object state, make it an instance method.
Situation
Recommended
Pure calculation, no state
Static, safe and cheap
Factory returning an instance
Static, hides the constructor
Reads instance fields
Instance method
Mutable state shared across objects
Avoid, or pass it in as a parameter
Utility class
Static, with a private constructor and final
Meant to vary per subclass
Instance method, so overriding works
Hides an instance in a static field
Avoid, it breaks with multiple instances
9) Common Mistakes
Mistake
Symptom
Fix
Using this in a static method
Compile error
Pass the object in as a parameter.
Reading an instance field
Compile error
Make it an instance method.
@Override on a static method
Compile error
Remove it, hiding is not overriding.
Expecting a static call to be polymorphic
The base version runs
Make the method an instance method.
Storing an instance in a static field
Shared state across objects
Keep it per instance.
Incrementing a static counter unsafely
Lost updates under threads
Use an atomic wrapper or a lock.
Utility class with a public constructor
Pointless instances
Make the constructor private, class final.
Static method that really is per-object
Awkward parameters
Reconsider as an instance method.
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.
// 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.
Share with friends, students, or your developer network
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.
Stay Updated
Enable Notifications?
Get real-time updates, instant tool alerts & daily news directly on your device.