Java Variable Scope — Local, Instance, Class & Block Scope

3 minute read

Scope determines where a variable is accessible and how long it lives. Understanding scope prevents bugs and helps you write cleaner code.


Types of Variable Scope

Scope Declared In Accessible In Lifetime
Local Method or block That method/block only Method/block execution
Instance Class (no static) All methods via this Object lifetime
Class (static) Class (with static) All methods via class name Program lifetime
Block if, for, while, etc. That block only Block execution

Local Variables

Declared inside a method. Only accessible within that method.

public static void greet() {
    String message = "Hello";  // local variable
    System.out.println(message);
}

public static void main(String[] args) {
    greet();
    // System.out.println(message);  // ERROR — not accessible here
}

Must Be Initialized Before Use

int x;
// System.out.println(x);  // ERROR — not initialized

int y = 10;
System.out.println(y);  // OK

Block Scope

Variables declared inside a block ({ }) are only accessible within that block.

if (true) {
    int x = 10;
    System.out.println(x);  // OK
}
// System.out.println(x);  // ERROR — x is out of scope
for (int i = 0; i < 5; i++) {
    System.out.println(i);  // OK
}
// System.out.println(i);  // ERROR — i is out of scope

Loop Variable Reuse

// This is fine — each loop has its own 'i'
for (int i = 0; i < 3; i++) {
    System.out.println(i);
}
for (int i = 0; i < 3; i++) {  // new 'i', no conflict
    System.out.println(i);
}

Instance Variables (Fields)

Declared in a class without static. Each object gets its own copy.

public class Person {
    String name;     // instance variable
    int age;         // instance variable

    public void introduce() {
        // accessible here
        System.out.println("I'm " + name + ", age " + age);
    }
}

Person p1 = new Person();
p1.name = "Alice";
p1.age = 25;

Person p2 = new Person();
p2.name = "Bob";
p2.age = 30;

Instance variables have default values (unlike local variables):

Type Default
int, long, etc. 0
double, float 0.0
boolean false
Objects, String null

Class (Static) Variables

Declared with static. Shared across all instances.

public class Counter {
    static int count = 0;  // class variable — shared

    public Counter() {
        count++;
    }
}

new Counter();
new Counter();
new Counter();
System.out.println(Counter.count);  // 3

Variable Shadowing

A local variable can shadow (hide) an instance variable with the same name:

public class Person {
    String name = "Default";  // instance variable

    public void setName(String name) {  // parameter shadows field
        // 'name' here refers to the PARAMETER
        this.name = name;  // 'this.name' refers to the FIELD
    }
}

Use this to distinguish between the field and the local/parameter variable.


Scope Rules Summary

public class ScopeDemo {
    static int classVar = 1;      // class scope
    int instanceVar = 2;           // instance scope

    public void method() {
        int localVar = 3;          // method scope

        if (true) {
            int blockVar = 4;      // block scope
            // all 4 variables accessible here
        }
        // blockVar NOT accessible here
    }
    // localVar NOT accessible here
}
// instanceVar, classVar NOT accessible here (without object/class)

Best Practices

  1. Declare variables in the narrowest scope possible.
    // Bad — declared too early
    int result;
    // ... 50 lines of code ...
    result = calculate();
    
    // Good — declared where used
    int result = calculate();
    
  2. Avoid shadowing — use different names for clarity.

  3. Prefer local variables over instance/class variables when possible.

  4. Use final for variables that shouldn’t change:
    final int MAX_SIZE = 100;
    

Quick Exercises

  1. What happens if you try to use a for loop variable outside the loop?
  2. Create a class with an instance variable and a method that has a local variable with the same name. Print both.
  3. Create a static counter that tracks how many objects have been created.

Summary

  • Local: Inside method, must initialize, dies when method ends
  • Block: Inside {}, dies when block ends
  • Instance: Per object, has default values, lives with object
  • Static: Per class, shared, lives with program
  • Use this to resolve shadowing

What’s Next?

Methods can call themselves — that’s recursion. Let’s explore this powerful technique: Recursion.

Updated: