Java static Keyword
Updated 8 min read Aimerscrew
Every field you've written in this chapter belonged to one object: each ticket had its own number, each account its own balance. But some data belongs to the whole group, like "how many tickets have we sold in total?" The Java static keyword handles exactly that. In this lesson, you'll learn static fields, static methods and static blocks, why main is static, and how to fix the famous "non-static ... cannot be referenced from a static context" error.
🌍 Real-life example
In a parking garage, every car has its own plate number. But the sign at the entrance that says "Free spots: 48" belongs to the garage, not to any one car. There's only one sign, and every car that enters or leaves updates it. Plate numbers are like instance fields; the free-spots sign is like a static field.
What does static mean in Java?
static means "belongs to the class, not to individual objects". Members without static are called instance members, because each instance (object) gets its own. Static members exist exactly once, no matter how many objects you create, even zero.
Static fields: one copy shared by all objects
Here's a ticket machine. Each ticket has its own number and holder, but the count of issued tickets is static, so all tickets share one counter:
public class TicketCounter {
public static void main(String[] args) {
System.out.println("Tickets so far: " + Ticket.issued);
Ticket a = new Ticket("Ana");
Ticket b = new Ticket("Ben");
Ticket c = new Ticket("Chloe");
a.show();
b.show();
c.show();
System.out.println("Tickets so far: " + Ticket.issued);
}
}
class Ticket {
static int issued = 0; // ONE copy, shared by all tickets
int number; // each ticket has its own
String holder;
Ticket(String holder) {
issued++;
this.number = issued;
this.holder = holder;
}
void show() {
System.out.println("Ticket #" + number + " for " + holder);
}
}
Tickets so far: 0
Ticket #1 for Ana
Ticket #2 for Ben
Ticket #3 for Chloe
Tickets so far: 3
issued lives once, in the class. Each object has its own number.Notice Ticket.issued in main: you reach a static field through the class name, and it works even before any ticket exists. If issued weren't static, every ticket would have its own counter, and each one would just say 1.
Static constants
A very common combination is static final: one shared copy that can never change. That's how Java code usually defines constants, which you first met in Java constants:
public class TaxDemo {
public static void main(String[] args) {
Product mug = new Product("Mug", 12.0);
Product lamp = new Product("Lamp", 40.0);
mug.printWithTax();
lamp.printWithTax();
}
}
class Product {
static final double SALES_TAX = 0.08; // a shared constant
String name;
double price;
Product(String name, double price) {
this.name = name;
this.price = price;
}
void printWithTax() {
System.out.printf("%s: $%.2f with tax%n", name, price * (1 + SALES_TAX));
}
}
Mug: $12.96 with tax
Lamp: $43.20 with tax
There's no point storing the tax rate in every product; one copy is enough. You've already used constants like this: Math.PI is a static final field of the Math class.
Static methods
A static method belongs to the class and is called with the class name. It doesn't work on any particular object, so it's perfect for utility methods: helpers that take some input and return a result. All the methods you wrote in Java methods were static for exactly this reason.
public class Converter {
public static void main(String[] args) {
System.out.println("25 C = " + Units.celsiusToFahrenheit(25) + " F");
System.out.println("10 km = " + Units.kmToMiles(10) + " miles");
System.out.println("Bigger of 7 and 12: " + Math.max(7, 12));
System.out.println("Square root of 81: " + Math.sqrt(81));
}
}
class Units {
static double celsiusToFahrenheit(double celsius) {
return celsius * 9 / 5 + 32;
}
static double kmToMiles(double km) {
return Math.round(km * 0.621371 * 100) / 100.0;
}
}
25 C = 77.0 F
10 km = 6.21 miles
Bigger of 7 and 12: 12
Square root of 81: 9.0
Units.kmToMiles(10) and Math.max(7, 12) work the same way: class name, dot, method. Nobody writes new Math(); every method in the Java Math class is static.
Static vs instance: comparison table
| Static member | Instance member | |
|---|---|---|
| Belongs to | The class | Each object |
| How many copies | Exactly one | One per object |
| How to call or read | ClassName.member | objectVariable.member |
| Needs an object? | No | Yes |
Can use this? | No | Yes |
| Can use instance fields directly? | No | Yes |
| Typical use | Counters, constants, utility methods | The object's own data and behavior |
Why can't a static method use instance fields?
A static method runs without any object, so there's no "current object" whose fields it could use. If main tries to call an instance method directly, the compiler can't know which object you mean:
public class StaticError {
String greeting = "Hello!";
void greet() {
System.out.println(greeting);
}
public static void main(String[] args) {
greet();
}
}
This produces one of the most common Java errors of all:
error: non-static method greet() cannot be referenced from a static context
greet();
^
The fix is to create an object first and call the method through it:
public class StaticFixed {
String greeting = "Hello!";
void greet() {
System.out.println(greeting);
}
public static void main(String[] args) {
StaticFixed app = new StaticFixed(); // make an object first
app.greet(); // then call through it
}
}
Hello!
The other direction is always fine: an instance method can use static fields and methods, as the Ticket constructor did with issued.
⚠️ Don't fix it the wrong way
When beginners see this error, they often add static to everything until it compiles. That works for tiny programs but defeats the purpose of objects: static fields are shared, so every "object" would end up with the same data. Make a member static only when it truly belongs to the whole class.
Why is the main method static?
When you run java TicketCounter.java, the JVM needs to start your program, but no objects exist yet. If main were an instance method, the JVM would have to create an object first, and it wouldn't know which constructor to call or what arguments to pass. Because main is static, the JVM can call TicketCounter.main(args) straight away, using just the class name. That's the whole reason for public static void main: public so the JVM can see it, static so it needs no object, and void because it returns nothing.
Static blocks
A static block (also called a static initializer) is a block of code marked static that runs once, when the class is first used. It's handy when setting up a static field takes more than one line:
public class StaticBlock {
public static void main(String[] args) {
System.out.println("main starts");
System.out.println("Sizes: " + Shop.sizes[0] + ", " + Shop.sizes[1] + ", " + Shop.sizes[2]);
}
}
class Shop {
static String[] sizes = new String[3];
static {
System.out.println("Shop class is loading...");
sizes[0] = "S";
sizes[1] = "M";
sizes[2] = "L";
}
}
main starts
Shop class is loading...
Sizes: S, M, L
Look at the order: the block didn't run at program start. It ran the first time the code touched Shop. You won't need static blocks often, but now you'll recognize them.
Real-world example: a parking garage
Here's the garage from the start of the lesson. The capacity and the number of parked cars are shared by all cars; each car keeps its own plate. A static method shows the sign:
public class ParkingGarage {
public static void main(String[] args) {
ParkedCar.showFreeSpots();
ParkedCar one = new ParkedCar("KL-55");
ParkedCar two = new ParkedCar("TX-901");
ParkedCar.showFreeSpots();
one.leave();
ParkedCar.showFreeSpots();
System.out.println(two.plate + " is still parked.");
}
}
class ParkedCar {
static final int CAPACITY = 50;
static int parked = 0;
String plate;
ParkedCar(String plate) {
this.plate = plate;
parked++;
}
void leave() {
parked--;
System.out.println(plate + " left the garage.");
}
static void showFreeSpots() {
System.out.println("Free spots: " + (CAPACITY - parked) + " of " + CAPACITY);
}
}
Free spots: 50 of 50
Free spots: 48 of 50
KL-55 left the garage.
Free spots: 49 of 50
TX-901 is still parked.
showFreeSpots() only uses static fields, so it can be static. leave() needs the car's own plate, so it must be an instance method.
Common mistakes with static
1. Calling an instance method from main
"non-static method cannot be referenced from a static context" means you need an object: create one with new and call the method on it.
2. Making per-object data static
If holder were static, every ticket would show the last name assigned, because there would be only one holder for all of them.
3. Using this in a static method
There's no current object in a static method, so this doesn't exist there.
4. Calling static members through an object
a.issued compiles, but it hides the fact that the value is shared and confuses readers. Always write Ticket.issued.
Practice exercise
🏋️ Try it yourself
Create a Visitor class for a museum. Each visitor has a name. Use a static field to count how many visitors are inside, adding 1 in the constructor and subtracting 1 in an instance method exit(). Add a static method printCount(). In main, let three visitors in, let one leave, and print the count after each step.
Show solution
public class Museum {
public static void main(String[] args) {
Visitor.printCount();
Visitor ada = new Visitor("Ada");
Visitor ben = new Visitor("Ben");
Visitor cleo = new Visitor("Cleo");
Visitor.printCount();
ben.exit();
Visitor.printCount();
System.out.println(ada.name + " and " + cleo.name + " are still inside.");
}
}
class Visitor {
static int inside = 0;
String name;
Visitor(String name) {
this.name = name;
inside++;
}
void exit() {
inside--;
System.out.println(name + " left.");
}
static void printCount() {
System.out.println("Visitors inside: " + inside);
}
}
Visitors inside: 0
Visitors inside: 3
Ben left.
Visitors inside: 2
Ada and Cleo are still inside.
What's next?
As programs grow, putting every class in one file stops working. Next, learn Java packages: how to organize classes into folders, use import, and compile multi-file programs.
Key takeaways
- static members belong to the class; instance members belong to each object.
- A static field has exactly one copy shared by all objects, such as a counter of created objects.
- static final fields are shared constants, such as Math.PI.
- Call static members with the class name: Ticket.issued, Math.max(7, 12).
- Static methods cannot use instance fields, instance methods or this directly.
- main is static so the JVM can call it before any object exists.
- A static block runs once, when the class is first used.
Frequently asked questions
What does static mean in Java?
static means a field or method belongs to the class itself rather than to individual objects. There is only one copy of a static field, and a static method can be called without creating an object.
What is the difference between static and instance variables?
A static variable has one copy shared by all objects of the class. An instance variable has a separate copy in each object, so every object can hold a different value.
Why is the main method static in Java?
The JVM has to call main before any objects exist. Because main is static, it can be called using only the class name, without creating an object first.
How do I fix "non-static method cannot be referenced from a static context"?
Create an object of the class and call the method through it, for example App app = new App(); app.run();. Only make the method static if it really does not need any object data.
Can a static method call an instance method?
Not directly. It needs an object reference first, for example a parameter or an object it creates with new. An instance method, on the other hand, can call static methods freely.