Skip to main content

static Keyword in Java: Variables, Methods, Blocks and Nested Classes

The static keyword in Java explained with real output: static variables, methods, blocks and nested classes, the exact initialisation order, why main is static (and Java 25 instance main), and the static bugs that reach production. Verified on JDK 25.

The static keyword makes a member belong to the class instead of to any one object. A static field has exactly one copy, shared by every instance. A static method runs without an object, so it cannot touch this or any instance member. A static block runs once, when the class is first initialised.
CLASS: StaticVsInstancestatic int created = 2static String describe()ONE copy, no object neededobject aint id = 1object bint id = 2instance fields: ONE COPY PER OBJECTStatic belongs to the class and exists once; instance data belongs to each object.
Left: the class holds one shared created counter. Right: each object has its own id, and every object sees the same counter. The rest of this page covers where that memory lives, the exact order in which static and instance code runs (from a real run), nested vs inner classes, why main is static, and the bugs that come from sharing state by accident. Everything was compiled and run on JDK 25.
Versions. Every program on this page was compiled and run on JDK 25.0.4.1 (Temurin, LTS, build 25.0.4.1+1-LTS). Where Java 8 behaved differently the text says so. The compiler errors and console output are quoted verbatim from those runs; the “Download” links at the end of each section point to the exact .java files.

Static vs instance members

Static memberInstance member
Belongs toThe classEach object
CopiesOneOne per object
Needs an object to useNo (ClassName.member)Yes
Can use thisNoYes
Can access instance membersNo (no object to read them from)Yes
Can access static membersYesYes
CreatedWhen the class is initialisedWhen new runs
The example below counts objects with a static field and gives each object its own id. Source: StaticVsInstance.java.
public class StaticVsInstance {
    static int created = 0;          // one copy, shared by every object
    final int id;                    // one copy per object

    StaticVsInstance() { id = ++created; }

    static String describe() { return "created so far: " + created; }
$ java StaticVsInstance.java
a.id=1 b.id=2 created so far: 2
Two objects were created, so created is 2 for everyone, while id is 1 and 2 because it was copied per object at construction time. The static method describe() could read created directly but could not have read id.

What the compiler refuses

Using an instance member from a static method is the most common beginner error. BrokenStatic.java does it three ways:
public class BrokenStatic {
    int count = 0;
    void bump() { count++; }
    public static void main(String[] args) {
        count = 5;
        bump();
        System.out.println(this.count);
    }
}
$ javac BrokenStatic.java
BrokenStatic.java:5: error: non-static variable count cannot be referenced from a static context
        count = 5;
        ^
BrokenStatic.java:6: error: non-static method bump() cannot be referenced from a static context
        bump();
        ^
BrokenStatic.java:7: error: non-static variable this cannot be referenced from a static context
        System.out.println(this.count);
                           ^
3 errors
A static method has no object, so there is no count to read, no bump() to call on, and no this. The fix is either to make the member static too, or to create an object and call the method on it.

Where static members live

Conceptually, static fields belong to the loaded class and exist once per class loader. In HotSpot (the JVM in Oracle and OpenJDK builds), since Java 8 static field values are stored in the java.lang.Class object on the heap; the language only promises one copy per class, not a storage location. The practical consequences are what matter: a static field lives as long as its class is loaded (usually until the JVM exits), so anything it references is not garbage collected, and its value is visible to every thread.

Static initialisation: the exact order

Static initialisers run once, when the class is first initialised (first new, first static method call, or first read of a non-constant static field). Instance initialisers run on every new, before the constructor body. StaticInitOrder.java prints each step:
public class StaticInitOrder {
    static int counter = log("static field initializer");
    int instanceField = log("instance field initializer");

    static { log("static block"); }
    { log("instance block"); }

    StaticInitOrder() { log("constructor"); }

    static int log(String what) {
        System.out.println("  " + what);
        return 1;
    }
$ java StaticInitOrder.java
  static field initializer
  static block
main starts (static block above already ran)
new #1:
  instance field initializer
  instance block
  constructor
new #2:
  instance field initializer
  instance block
  constructor
The static field initialiser and static block ran first, in the order they appear in the source, and before main printed its first line. Then each new repeated the same instance sequence: instance field initialiser, instance block, constructor.
ONCE per classstatic fields and static blocks(in source order)EVERY newinstance fields and instance blocks,then the constructor body
Each box is a stage; the left one is never repeated. If a class has a superclass, the superclass goes through both stages first (static before static, instance before instance), which is covered in Constructors in Java.

Constants do not trigger class initialisation

The nested class Lazy in the same file has a static final int CONSTANT = 42 and an ordinary static int value:
    static class Lazy {
        static { log("Lazy class initialised"); }
        static final int CONSTANT = 42;          // compile-time constant: does not trigger init
        static int value = 7;                    // ordinary static: does
    }
$ java StaticInitOrder.java
reading Lazy.CONSTANT = 42
reading Lazy.value:
  Lazy class initialised
  value = 7
Reading CONSTANT did not print “Lazy class initialised”, because a compile-time constant is inlined into the caller. Reading value did, because it is a real static field. This is a useful fact when a class’s static block has side effects.
Exception in a static block. If a static initialiser throws, the class fails to initialise: the first use gives ExceptionInInitializerError and every later use gives NoClassDefFoundError for the same class. Keep static blocks free of work that can fail, or the real cause is easy to miss in a log.

Static methods: what they can and cannot do

A static method is resolved from the class, not from the object. That has three consequences:
  • No overriding. A same-signature static in a subclass hides the parent’s method; see Method Overloading vs Overriding.
  • No this or super. There is no current object.
  • Calling it through an instance is legal but misleading. The reference type is used and the object is ignored.
The last point is easy to demonstrate. In StaticVsInstance.java a null reference reads a static field:
        StaticVsInstance nothing = null;
        System.out.println("static via null reference: " + nothing.created);
$ java StaticVsInstance.java
static via null reference: 2
No NullPointerException: the compiler turned nothing.created into StaticVsInstance.created and never looked at the reference. Always write ClassName.member for statics.

Nested vs inner classes

A static nested class is just a class declared inside another for organisation; it has no link to an outer object. A non-static (inner) class holds a hidden reference to the object that created it.
$ java StaticVsInstance.java
inner of #2
nested, no enclosing object, created=2
fields in Inner: [final StaticVsInstance StaticVsInstance$Inner.this$0]
fields in Nested: []
The reflection output shows the difference: Inner has a synthetic this$0 field pointing at the enclosing object, while Nested has no fields at all. That hidden reference is why an inner class instance can keep its outer object alive, and why long-lived callbacks are safer written as static nested classes or lambdas that capture only what they need. Prefer static nested unless the class genuinely needs the outer instance.

Why main is static

StaticBugs.java prints its own modifiers by reflection:
        System.out.println("main is static because the JVM calls it with no object: "
                + java.lang.reflect.Modifier.toString(
                    StaticBugs.class.getDeclaredMethod("main", String[].class).getModifiers()));
$ java StaticBugs.java
main is static because the JVM calls it with no object: public static
The JVM must call main before any object of your class exists, so a static method is the only thing it can call without constructing one. That is also why public static void main(String[] args) has been the required entry point since Java 1.0.

Java 25: instance main is allowed

In Java 25 (JEP 512), the launcher can also start an instance main with no static, no public, and no parameters; it creates the object for you. InstanceMain.java:
class InstanceMain {
    void main() {
        IO.println("no static, no String[] args, no public: Java 25 launches this");
    }
}
$ java InstanceMain.java
no static, no String[] args, no public: Java 25 launches this
The traditional signature still works and is what older tools and tutorials expect. The full story, including compact source files, is in Compact Source Files and Instance Main Methods in Java 25 (JEP 512).

Static bugs that reach production

Sharing is the feature and the hazard. StaticBugs.java declares per-request data as a static field by mistake:
    static class Request {
        static String user;                            // bug: shared by every request
        Request(String u) { user = u; }
    }

    public static void main(String[] args) throws Exception {
        Request r1 = new Request("asha");
        Request r2 = new Request("ravi");
        System.out.println("r1 sees user = " + Request.user);   // ravi
$ java StaticBugs.java
r1 sees user = ravi
The first request was created for asha, yet it reports ravi, because the second constructor call overwrote the one shared field. In a web application this becomes one user seeing another user’s data. The same mistake with a static SimpleDateFormat, ArrayList or HashMap used from several threads causes corrupted state; see Java HashMap vs ConcurrentHashMap and Top 40 Java Concurrency Interview Questions.
Rule of thumb. Use static for constants (static final), pure utility methods, factory methods and a deliberately shared counter or cache. Do not use it for state that belongs to a request, a user or a test, and avoid mutable static state in anything that runs on more than one thread.

Going deeper

Download the code. StaticVsInstance.java · StaticInitOrder.java · StaticBugs.java · BrokenStatic.java · InstanceMain.java.

Run a runnable one with java File.java (JDK 11 or later; JDK 25 recommended). Files starting with Broken are meant to fail to compile.

Common interview questions

1. What does the static keyword do in Java?

It makes a field, method, block or nested class belong to the class rather than to an object. A static field has one copy shared by all instances.

2. Can a static method access instance variables?

Not directly. It has no this, so it needs an object reference to reach an instance member; otherwise the compiler reports non-static variable cannot be referenced from a static context.

3. Why is the main method static?

The JVM calls it before any object exists. From Java 25 an instance main is also allowed by the launcher (JEP 512).

4. When does a static block run?

Once, when the class is first initialised (first object creation, static method call, or non-constant static field access), in source order with the static field initialisers.

5. What is the order of static block, instance block and constructor?

Static initialisers once, then for each new object: instance field initialisers and instance blocks in source order, then the constructor body. Superclass steps come first.

6. Can we override a static method?

No. It is hidden, and the declared type of the reference decides which one runs.

7. Can a static method be abstract, or a constructor static?

No on both. Abstract needs overriding; constructors initialise a specific object.

8. What is the difference between a static nested class and an inner class?

A static nested class has no reference to an outer object. An inner class holds a hidden reference (this$0) to its creating outer instance.

9. What is a static import?

import static pkg.Class.member; lets you use a static member without the class name. Use it sparingly, mainly for constants and test assertions.

10. Does static final trigger class initialisation?

Not when it is a compile-time constant, because the value is inlined; the run above shows it.

11. Is a static variable thread-safe?

No. It is shared by all threads, so mutable statics need synchronisation, atomics or a thread-safe type.

12. Can you access a static member through a null reference?

Yes, it works and does not throw, because the compiler uses the declared type; the run above shows it. Avoid writing it that way.

13. When is a static variable garbage collected?

When its class is unloaded, which usually means when its class loader is collected, not while the application is running normally.

Common mistakes

  • Putting per-request or per-user data in a static field. Everyone shares it.
  • Mutable static collections used from several threads. Use concurrent types or avoid the static.
  • Calling statics through an instance. It compiles, hides intent, and never throws on null.
  • Heavy or failing work in a static block. It runs once and a failure poisons the class.
  • Making everything static to avoid creating objects. It makes testing and substitution hard.
  • Using an inner class where a static nested class would do. The hidden outer reference can keep large objects alive.

FAQ

What is the static keyword in Java?

It marks a member as belonging to the class instead of to individual objects. A static field has one shared copy, a static method needs no object, and a static block runs once when the class is initialised.

Why is main static in Java?

The JVM has to call main before any object exists, so it must be callable on the class itself. Java 25 also lets the launcher start an instance main method.

What is the difference between static and non-static in Java?

Static members belong to the class and exist once; non-static (instance) members belong to each object. Static methods cannot use this or instance members directly.

What is the order of execution of static block, instance block and constructor in Java?

Static blocks and static field initialisers run once when the class is first initialised. For every new object, instance initialisers run, then the constructor body. Superclass steps run before subclass steps.

What is the difference between a static nested class and an inner class?

A static nested class does not hold a reference to an outer object. An inner class does, through a hidden this$0 field, so it needs an enclosing instance.

Where to go next

Other articles in this Java fundamentals series:

No Comments yet!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.