Skip to main content
DevHivesBlog

Search the blog

Find a post by title, tag or topic

Static vs Non-Static in Java: Differences With Examples

A static member belongs to the class and is shared. A non-static member belongs to each object. See the difference in code, with the famous compiler error explained.

Arnab Biswas7 min read
WhatsApp
An amber STATIC rubber stamp, the Java keyword that gives a class one shared copy of a member

Say you write a Java class called Student. You add a field college and mark it static by accident. Now every student object shows the same college, and changing one changes all of them. The bug is one keyword long, and it is one of the most common mistakes in first-year Java.

The keyword static decides who owns a member of a class: the class itself, or each object made from it. This post shows the difference with code you can compile, then the rules that cause the famous compiler error.

A static member belongs to the class and exists once. A non-static member belongs to each object, so every object gets its own copy. You reach a static member with the class name, and a non-static member only through an object. That one rule explains almost every error message you will see about static.

Static vs non-static: side-by-side table

Read this table first. The sections below explain each row with code.

PointStaticNon-static (instance)
Belongs toThe classEach object
Copies in memoryOne, sharedOne per object
How to callClassName.memberobject.member
Needs an object?NoYes
Can use this?NoYes
Can use the other kind directly?Only static membersBoth static and non-static
Typical useCounters, constants, helper methodsData that differs per object

Static variable vs instance variable

Java stores a static variable once, with the class. It stores an instance variable inside each object, on the heap. The Oracle Java tutorial on class members uses a bicycle example for exactly this idea: gear and speed belong to each bicycle, while a count of bicycles belongs to the class.

Here is a small class that counts how many objects were created. The counter must be shared, so it is static. Each object's own count must be separate, so it is not.

public class Counter {
    static int totalCreated = 0;     // one copy, shared by all objects
    int count = 0;                   // one copy per object
    Counter() {
        totalCreated++;
    }
    void increment() {               // non-static method
        count++;
    }
    static int getTotalCreated() {   // static method
        return totalCreated;
    }
    public static void main(String[] args) {
        Counter a = new Counter();
        Counter b = new Counter();
        a.increment();
        a.increment();
        b.increment();
        System.out.println(a.count);                   // 2
        System.out.println(b.count);                   // 1
        System.out.println(Counter.getTotalCreated()); // 2
    }
}

Object a has a count of 2 and object b has a count of 1. Both objects see the same totalCreated, which is 2. This code compiles and prints exactly those three numbers.

Static method vs non-static method

You call a static method on the class itself, and main is the best-known case: the JVM must start your program before any object exists. The Java language specification describes this under class methods.

A non-static method needs an object, because it works on that object's data.

public class Utils {
    static int square(int n) { return n * n; }
    int cube(int n) { return n * n * n; }
    public static void main(String[] args) {
        System.out.println(Utils.square(4));       // 16, no object needed
        System.out.println(new Utils().cube(3));   // 27, object needed
        System.out.println(Math.max(3, 9));        // 9, a static method from the JDK
    }
}

Math.max is a good example from the Java library. You never write new Math(), because a maximum does not depend on any object's data.

A useful test: look at the method body. If it reads or changes only its parameters, it can be static. If it reads this.name or any other field of the object, it cannot.

Can static methods access non-static variables?

No, and the reason is timing. The variable lives inside an object, and a static method may run before any object has been created.

This is the code that gives the famous error:

public class BadAccess {
    int age = 20;
    public static void main(String[] args) {
        System.out.println(age);
    }
}

The compiler stops with: non-static variable age cannot be referenced from a static context. Java is asking one question: which object's age do you mean? You have two fixes. Build an object and read the field through it, or move the field to the class by making it static.

public class StaticAccess {
    int age = 20;
    static String college = "DevHives College";
    static void show() {
        System.out.println(college);       // OK: static uses static
        StaticAccess s = new StaticAccess();
        System.out.println(s.age);         // OK: through an object
    }
    void print() {
        System.out.println(age + " " + college); // OK: non-static can use both
    }
    public static void main(String[] args) {
        show();
        new StaticAccess().print();
    }
}

The opposite direction always works. When an object exists, its class is already loaded, so the object's methods can read every static field.

Static block in Java

Java runs a static block one time, when it first loads the class. People use it for setup that must finish before anything else, such as filling a lookup table. The matching tool for objects is the instance initializer block, which runs before the constructor each time you create an object.

public class StaticBlock {
    static int answer;
    int id;
    static {
        System.out.println("static block runs once");
        answer = 42;
    }
    {
        System.out.println("instance block runs for every object");
        id = 7;
    }
    StaticBlock() {
        System.out.println("constructor runs");
    }
    public static void main(String[] args) {
        System.out.println("main starts, answer = " + answer);
        new StaticBlock();
        new StaticBlock();
    }
}

The output order is the lesson. The static block prints first, then main starts. After that, each new StaticBlock() prints the instance block line and then the constructor line, twice in total.

  1. Class loads

    Static variables get values and the static block executes.

  2. Object is created

    Instance variables get default values.

  3. Instance block runs

    Any { ... } block in the class body executes.

  4. Constructor runs

    Your constructor finishes the setup.

Static class vs non-static class

Java allows the static keyword on a class only when the class sits inside another class. A top-level class cannot use the keyword. You can create a static nested class without any outer object. A non-static nested class (called an inner class) always belongs to an outer object.

public class Outer {
    int x = 10;
    static class StaticNested {
        void hello() { System.out.println("no outer object needed"); }
    }
    class Inner {
        void show() { System.out.println("x = " + x); }  // can read the outer x
    }
    public static void main(String[] args) {
        new StaticNested().hello();
        Outer o = new Outer();
        Outer.Inner in = o.new Inner();
        in.show();
    }
}

A nested class that never reads the outer object's fields should be static. Then it carries no hidden reference, so it cannot keep the outer object alive by accident.

Static final constants and static imports

The most common safe use of static is a constant. Add final so nobody can change the value, and name it in capital letters.

public class Config {
    static final int MAX_LOGIN_TRIES = 3;
    static final String APP_NAME = "DevHives Portal";
    public static void main(String[] args) {
        System.out.println(APP_NAME + " allows " + Config.MAX_LOGIN_TRIES + " tries");
    }
}

One copy of each constant exists, so a thousand objects do not waste memory repeating it. Java also lets you write import static java.lang.Math.max; and then call max(3, 9) without the class name. Use that sparingly, because the reader can no longer see where max came from.

Static and threads

A shared static variable can be changed by several threads at once, and the result can be wrong. Say two threads both run totalCreated++ in the Counter class. The increment is really three steps: read, add, write. Two threads can read the same old value, so one update is lost.

For a counter that many threads touch, use AtomicInteger instead of a plain static int. For constants, no risk exists, because nobody changes them.

An interview question: can you override a static method?

No. If a child class declares a static method with the same signature, it hides the parent method instead of overriding it. Overriding works on objects at run time. Hiding is decided by the variable's declared type when the code is compiled.

class Parent {
    static void who() { System.out.println("Parent"); }
}
class Child extends Parent {
    static void who() { System.out.println("Child"); }
}
public class HideDemo {
    public static void main(String[] args) {
        Parent p = new Child();
        p.who();          // prints Parent, because the declared type is Parent
        Child.who();      // prints Child
    }
}

Many interviewers also ask whether a constructor can be static (it cannot) and whether this works inside a static method (it does not). Both answers follow from the same rule: static has no current object.

When to use static, and when not to

Use static for

  • Constants, such as static final double PI
  • Helper methods that use only their parameters
  • A counter or setting shared by every object

Avoid static for

  • Data that is different for each object, like a student's name
  • Anything you want to replace with a fake in a test
  • Mutable shared state that many threads change

My own rule is simple: start every member as non-static. Make it static only when you can say, in one sentence, why all objects must share it. Beginners often reach for static to silence the compiler error above. That fixes the error and creates a design problem.

Common mistakes

  • Calling a static method through an object. obj.staticMethod() compiles, but it hides the fact that no object is used. Write ClassName.staticMethod().
  • Using this in a static method. There is no current object, so the compiler rejects it.
  • Making a field static to fix an error. Every object then shares one value, which is the bug from the start of this post.
  • Expecting a static method to be overridden. Static methods are hidden, not overridden. The method that runs depends on the variable's declared type.

What to do next

If you are still building your Java base, follow the free Java course syllabus first. Then open an editor and copy Counter from above. Add a second static variable and a second non-static variable, then print both from two objects. Predict each output before you run it. When your predictions match every time, you understand static. Push the file to a repository with a clear README, as shown in this GitHub README guide, so you have proof of practice.

ShareWhatsAppLinkedInX

Picked from the tags and topic of this post.

A large question mark, symbolizing the uncertainty about which free Java course to choose in 2026.
study tips9 min read

Best Free Java Course for Beginners in 2026: Honest Picks

As of October 2026, the top-ranked Java MOOC is officially legacy. Here's the truly free course to start with, plus which "free" offers hide a certificate fee, and a five-step path to your first Java project.

Arnab Biswas