Java Static Variables

In the last lesson you learned about the Java static keyword. Now let’s use that idea on a field. Picture a counter for the total number of users ever created, where each object keeping its own count would not work. A static variable fixes exactly this. Let’s learn it.

πŸ€” The problem: where does a shared total live?

You create User objects and want to know how many exist in total. Here is the natural first try with a normal field.

class User {
int count = 0; // ❌ each object gets its own count
User() {
count = count + 1;
}
}
public class Main {
public static void main(String[] args) {
User a = new User();
User b = new User();
User c = new User();
System.out.println(a.count);
System.out.println(b.count);
System.out.println(c.count);
}
}

You might expect the total to climb to 3. But look at what prints.

Output

1
1
1

Every object printed 1. Here is why:

  • A normal field belongs to the object. Each User got its own private count, starting at zero.
  • There is no single place for the total to add up. The count is scattered across three objects.
  • We need one shared box that every object writes to. That is a static variable.

🧩 What is a static variable?

A static variable is a field that belongs to the class itself:

  • There is only one copy, shared by every object of the class.
  • Change it through one object, and all the others see the change.
  • People also call it a class variable.

Think of a shared whiteboard in an office. Each person has their own notebook (a normal field). The whiteboard is shared, so anyone can update it and everyone sees the same numbers (a static field). You make a field static by adding the static keyword.

class User {
static int count = 0; // one shared copy for the whole class
}

Now a single count is shared by the whole class. Let’s build the counter properly.

πŸ”’ The classic object-counter example

Put a static variable on the class and add one inside the constructor. The constructor runs once per new object, so the count rises by one each time.

class User {
static int count = 0; // shared by every User
String name;
User(String name) {
this.name = name;
count = count + 1; // every new object adds to the same total
}
}
public class Main {
public static void main(String[] args) {
User a = new User("Alex");
User b = new User("Sam");
User c = new User("Riya");
System.out.println("Users created: " + User.count);
}
}

Each new User(...) runs the constructor, and each run adds one to the shared count. After three objects, the count is three.

Output

Users created: 3

The three constructor calls all touched the same count, so the total added up correctly. We read it as User.count, no object needed.

πŸ†š Static variables vs instance variables

An instance variable is a normal field. Every object gets its own copy. A static variable has one copy shared by all objects. Here is a class with one of each, side by side.

class Player {
static int totalPlayers = 0; // one shared copy
String name; // each object has its own
int score; // each object has its own
Player(String name) {
this.name = name;
this.score = 0;
totalPlayers = totalPlayers + 1;
}
}
public class Main {
public static void main(String[] args) {
Player p1 = new Player("Alex");
Player p2 = new Player("Sam");
p1.score = 50; // changes only p1's own score
p2.score = 90; // changes only p2's own score
System.out.println(p1.name + " score: " + p1.score);
System.out.println(p2.name + " score: " + p2.score);
System.out.println("Total players: " + Player.totalPlayers);
}
}

Each player keeps a private score, so setting one does not touch the other. But totalPlayers is shared, so both objects added to the same total. The total came out as 2 because both constructors added to the one shared copy.

Output

Alex score: 50
Sam score: 90
Total players: 2

The simple rule of thumb

Ask one question: should every object have its own value, or should all objects share one value? Own value means an instance field. Shared value means a static field. A player’s score is their own. The total number of players belongs to everyone.

🏷️ Accessing static variables with ClassName

A static variable belongs to the class, so reach it as ClassName.variable, with no object. Here we read and change a static field through the class name.

class Settings {
static int volume = 5;
}
public class Main {
public static void main(String[] args) {
System.out.println("Start: " + Settings.volume);
Settings.volume = 8;
System.out.println("Now: " + Settings.volume);
}
}

We never created a Settings object. We just used the class name, where the variable lives.

Output

Start: 5
Now: 8

Java does let you reach a static field through an object, like someObject.volume. But do not. It looks like the value belongs to that object. Always use the class name.

πŸ”’ Static final constants

A constant is a value that never changes while the program runs, like a maximum limit. You make one with static final.

  • The static part shares one copy with the whole class.
  • The final part locks the value so it can never be reassigned.
  • By convention, constant names are in all capitals with underscores between words.
class Config {
static final int MAX_USERS = 100;
static final double PI = 3.14159;
static final String APP_NAME = "FreeCodingSchool";
}
public class Main {
public static void main(String[] args) {
System.out.println("App: " + Config.APP_NAME);
System.out.println("Max users allowed: " + Config.MAX_USERS);
System.out.println("Pi: " + Config.PI);
}
}

These values are shared everywhere and can never be changed by accident.

Output

App: FreeCodingSchool
Max users allowed: 100
Pi: 3.14159

Try to change a final constant and the program will not even compile.

Config.MAX_USERS = 200; // ❌ compile error: cannot assign a value to final variable

One fixed limit, defined in one place, that nobody can break. Change that single line and the whole program updates. Java’s library uses this pattern, like Math.PI and Integer.MAX_VALUE.

🏠 Where static variables live: the method area

When Java loads a class, it stores the class’s static variables in a part of memory called the method area.

  • The method area is created once at class load, and there is one for the whole program.
  • A static variable lives there with the class, not inside any object. That is why there is only one copy.
  • Objects live on the heap with their own instance fields, but they all point back to the single static field.

That difference in location is the whole reason static fields are shared.

⚠️ Common Mistakes

Using static for data that should be per-object. Make a field static when each object needs its own value, and every object ends up sharing and overwriting the same value.

class Player {
static int score; // ❌ all players now share one score!
}
class Player {
int score; // βœ… each player keeps their own score
}

Mutable shared static state causing surprise bugs. A static variable is shared, so code in one place can change it and break code elsewhere, with no obvious link. This is hard to debug.

class Counter {
static int value = 0; // ❌ any code anywhere can change this freely
void doWork() {
value = value + 1; // many places writing to one shared box
}
}
class Counter {
private static int value = 0; // βœ… keep it private, change it in one controlled place
static void increment() {
value = value + 1;
}
static int getValue() {
return value;
}
}

Forgetting that static is shared across objects. People expect each object to β€œreset” a static field. It does not reset. Whatever the last object wrote is what every object sees.

User a = new User();
User b = new User();
System.out.println(b.count); // ❌ surprised this is 2, not 1 β€” it is shared

βœ… Best Practices

  • βœ… Use a static variable only for data truly shared by the whole class, like a total count or a global setting.
  • βœ… Use an instance variable for anything each object owns, like a name, a score, or a balance.
  • βœ… Use static final for constants, named in ALL_CAPS.
  • βœ… Access static members through the class name (ClassName.var), never an object.
  • βœ… Keep mutable static fields private and change them through controlled methods. The fewer places that can write to it, the easier your program is to trust.

🧩 What You’ve Learned

  • βœ… A static variable belongs to the class, with one copy shared by every object.
  • βœ… The object-counter pattern increments a static count in the constructor, so all objects add to one total.
  • βœ… Instance variables give each object its own value; static variables share one value.
  • βœ… Access static fields with ClassName.var, no object needed.
  • βœ… static final makes shared constants like MAX_USERS and PI that can never change.
  • βœ… Static variables live in the method area, once per class, which is why they are shared.

Check Your Knowledge

Test what you learned. Pick an answer for each question, then click Check.

  1. 1

    How many copies of a static variable exist for a class?

    Why: A static variable belongs to the class, so there is exactly one copy shared by all objects.

  2. 2

    Why does the object-counter pattern increment count in the constructor?

    Why: Each new object runs the constructor once, and each run adds one to the single shared static count.

  3. 3

    What does static final create?

    Why: static shares one copy with the class and final locks the value, giving a shared constant.

  4. 4

    Where do static variables live in memory?

    Why: Static variables are stored with the class in the method area, which is why there is only one copy.

πŸš€ What’s Next?

Static variables let the class hold shared data. The natural partner is a method that belongs to the class instead of an object, so you can call it without creating anything first. That is exactly how Math.max and main work. Let’s learn it.

Java Static Methods

Share & Connect