Java Static Variables
Table of Contents + β
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
111Every object printed 1. Here is why:
- A normal field belongs to the object. Each
Usergot its own privatecount, 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: 3The 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: 50Sam score: 90Total players: 2The 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: 5Now: 8Java 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
staticpart shares one copy with the whole class. - The
finalpart 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: FreeCodingSchoolMax users allowed: 100Pi: 3.14159Try to change a final constant and the program will not even compile.
Config.MAX_USERS = 200; // β compile error: cannot assign a value to final variableOne 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 finalfor constants, named inALL_CAPS. - β
Access static members through the class name (
ClassName.var), never an object. - β
Keep mutable static fields
privateand 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
countin 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 finalmakes shared constants likeMAX_USERSandPIthat 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
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
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
What does static final create?
Why: static shares one copy with the class and final locks the value, giving a shared constant.
- 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.