Java course menu
Java Scope and static: Local Variables, Fields and Class Members
Understand variable scope in Java: block scope, local variables, why Java forbids shadowing locals, fields vs local variables, static fields and methods shared by the whole class, and instance members.
On this page
Every variable has a scope: the part of the code where its name can be used. Java's scope rules are simple and strict, and they explain many "cannot find symbol" errors. This lesson also explains the static keyword you have been writing since your first program.
Block scope#
A variable declared inside a block { } exists only from its declaration to the end of that block:
public class Main {
public static void main(String[] args) {
int total = 0;
for (int i = 1; i <= 3; i++) {
int square = i * i; // exists only inside the loop body
total += square;
}
System.out.println(total);
// System.out.println(square); // error: cannot find symbol
// System.out.println(i); // error: i belongs to the for loop
}
}14Declare variables in the smallest scope that needs them.
Local variables in methods#
Each method call has its own local variables, including its parameters. Two methods can use the same names without any conflict, and locals are discarded when the method returns:
public class Main {
static int doubleIt(int value) {
int result = value * 2;
return result;
}
public static void main(String[] args) {
int result = doubleIt(21); // a different 'result'
System.out.println(result);
}
}42No shadowing of locals#
Unlike C++, Java does not allow a local variable to be redeclared in a nested block of the same method:
public class Main {
public static void main(String[] args) {
int level = 1;
if (level > 0) {
int level = 99; // error: variable level is already defined
}
}
}This rule prevents a whole class of confusing bugs.
Fields: variables that belong to the class#
Variables declared inside a class but outside any method are fields. They are visible to every method in the class and live as long as their object (or class) does. Unlike local variables, fields get a default value (0, false, null) if you do not initialize them.
static: shared by the whole class#
A static field belongs to the class itself, so there is exactly one copy, shared by everything that uses the class. A static method also belongs to the class, and can be called without creating an object:
public class Counter {
static int requestCount = 0; // one shared counter
static void handleRequest() {
requestCount++;
}
public static void main(String[] args) {
handleRequest();
handleRequest();
handleRequest();
System.out.println(requestCount);
}
}3Familiar examples from the standard library: Math.sqrt(...), Integer.parseInt(...) and Math.PI are all static, so you call them on the class name.
static vs instance members#
Members without static are instance members: each object has its own copy of instance fields, and instance methods work on a particular object. You will use them throughout the OOP section; here is a preview:
public class Ticket {
static int issued = 0; // shared: counts all tickets
int number; // per object: each ticket has its own number
Ticket() {
issued++;
number = issued;
}
public static void main(String[] args) {
Ticket a = new Ticket();
Ticket b = new Ticket();
Ticket c = new Ticket();
System.out.println(a.number + " " + c.number);
System.out.println("Issued: " + Ticket.issued);
}
}1 3
Issued: 3Rules to remember:
- A static method cannot use instance fields or call instance methods directly, because there is no particular object (no
this). This is why calling a non-static helper frommainfails. - An instance method can use both instance and static members.
Effectively final variables#
Lambdas and anonymous classes (covered later) may only use local variables that are effectively final: never changed after initialization. If you see "local variables referenced from a lambda expression must be final or effectively final", the variable is reassigned somewhere.
Avoid mutable static state#
Like global variables in other languages, mutable static fields can be changed from anywhere, which makes bugs hard to trace and causes problems with multiple threads. Static constants (static final) and static utility methods (such as Math.max) are fine.
Common mistakes#
Practice#
Practice exercise
Write a class Logger with a static counter and a static method log(String text) that prints messages numbered [1] ..., [2] ... and so on. Log three messages.
Show solution
public class Logger {
static int count = 0;
static void log(String text) {
count++;
System.out.println("[" + count + "] " + text);
}
public static void main(String[] args) {
log("Started");
log("Loading");
log("Done");
}
}[1] Started
[2] Loading
[3] DoneKey takeaway#
Finished this lesson?