You declare int i inside a for loop. Outside the loop, i doesn't exist. Scope determines where a variable is visible. Understanding scope prevents bugs and helps you write cleaner, more predictable code.

Block scope

Variables exist only within their enclosing braces.

example
BlockScope.java
Replay: real traced execution (multi-file project)
public class BlockScope {
    public static void main(String[] args) {
        System.out.println("=== Block Scope ===\n");

        int outer = 10;
        System.out.println("outer = " + outer);

        {
            // Inner block - can see outer
            int inner = 20;
            System.out.println("  In block: outer = " + outer);
            System.out.println("  In block: inner = " + inner);

            // Nested block
            {
                int deepest = 30;
                System.out.println("    Deepest: outer = " + outer);
                System.out.println("    Deepest: inner = " + inner);
                System.out.println("    Deepest: deepest = " + deepest);
            }
            // deepest is gone here
        }

        // inner is no longer accessible here!
        System.out.println("After block: outer = " + outer);
        // System.out.println(inner);  // Error: cannot find symbol

        System.out.println("\n=== Scope Rule ===");
        System.out.println("Variables exist only in their { } block");
        System.out.println("Inner blocks can see outer variables");
        System.out.println("Outer blocks cannot see inner variables");
    }
}
public class BlockScope {
    public static void main(String[] args) {
        System.out.println("=== Block Scope ===\n");

        int outer = 3;
        System.out.println("outer = " + outer);

        {
            // Inner block - can see outer
            int inner = 20;
            System.out.println("  In block: outer = " + outer);
            System.out.println("  In block: inner = " + inner);

            // Nested block
            {
                int deepest = 30;
                System.out.println("    Deepest: outer = " + outer);
                System.out.println("    Deepest: inner = " + inner);
                System.out.println("    Deepest: deepest = " + deepest);
            }
            // deepest is gone here
        }

        // inner is no longer accessible here!
        System.out.println("After block: outer = " + outer);
        // System.out.println(inner);  // Error: cannot find symbol

        System.out.println("\n=== Scope Rule ===");
        System.out.println("Variables exist only in their { } block");
        System.out.println("Inner blocks can see outer variables");
        System.out.println("Outer blocks cannot see inner variables");
    }
}
public class BlockScope {
    public static void main(String[] args) {
        System.out.println("=== Block Scope ===\n");

        int outer = 42;
        System.out.println("outer = " + outer);

        {
            // Inner block - can see outer
            int inner = 20;
            System.out.println("  In block: outer = " + outer);
            System.out.println("  In block: inner = " + inner);

            // Nested block
            {
                int deepest = 30;
                System.out.println("    Deepest: outer = " + outer);
                System.out.println("    Deepest: inner = " + inner);
                System.out.println("    Deepest: deepest = " + deepest);
            }
            // deepest is gone here
        }

        // inner is no longer accessible here!
        System.out.println("After block: outer = " + outer);
        // System.out.println(inner);  // Error: cannot find symbol

        System.out.println("\n=== Scope Rule ===");
        System.out.println("Variables exist only in their { } block");
        System.out.println("Inner blocks can see outer variables");
        System.out.println("Outer blocks cannot see inner variables");
    }
}
public class BlockScope {
    public static void main(String[] args) {
        System.out.println("=== Block Scope ===\n");

        int outer = 10;
        System.out.println("outer = " + outer);

        {
            // Inner block - can see outer
            int inner = 5;
            System.out.println("  In block: outer = " + outer);
            System.out.println("  In block: inner = " + inner);

            // Nested block
            {
                int deepest = 30;
                System.out.println("    Deepest: outer = " + outer);
                System.out.println("    Deepest: inner = " + inner);
                System.out.println("    Deepest: deepest = " + deepest);
            }
            // deepest is gone here
        }

        // inner is no longer accessible here!
        System.out.println("After block: outer = " + outer);
        // System.out.println(inner);  // Error: cannot find symbol

        System.out.println("\n=== Scope Rule ===");
        System.out.println("Variables exist only in their { } block");
        System.out.println("Inner blocks can see outer variables");
        System.out.println("Outer blocks cannot see inner variables");
    }
}
public class BlockScope {
    public static void main(String[] args) {
        System.out.println("=== Block Scope ===\n");

        int outer = 10;
        System.out.println("outer = " + outer);

        {
            // Inner block - can see outer
            int inner = 100;
            System.out.println("  In block: outer = " + outer);
            System.out.println("  In block: inner = " + inner);

            // Nested block
            {
                int deepest = 30;
                System.out.println("    Deepest: outer = " + outer);
                System.out.println("    Deepest: inner = " + inner);
                System.out.println("    Deepest: deepest = " + deepest);
            }
            // deepest is gone here
        }

        // inner is no longer accessible here!
        System.out.println("After block: outer = " + outer);
        // System.out.println(inner);  // Error: cannot find symbol

        System.out.println("\n=== Scope Rule ===");
        System.out.println("Variables exist only in their { } block");
        System.out.println("Inner blocks can see outer variables");
        System.out.println("Outer blocks cannot see inner variables");
    }
}
  1. outer ← 10, inner ← 20, deepest ← 30

    2public class BlockScope {3    public static void main(String[] args) {4        System.out.println("=== Block Scope ===\n");5        6        int outer→ 10 = 10;  //@outer=10, 3, 427        System.out.println("outer = " + outer10);8        9        {  //?block10            // Inner block - can see outer11            int inner→ 20 = 20;  //@inner=20, 5, 10012            System.out.println("  In block: outer = " + outer10);13            System.out.println("  In block: inner = " + inner20);14            15            // Nested block  //@var=_,!16            {  //@var=_,!17                int deepest→ 30 = 30;  //@var=_,!18                System.out.println("    Deepest: outer = " + outer10);  //@var=_,!19                System.out.println("    Deepest: inner = " + inner20);  //@var=_,!20                System.out.println("    Deepest: deepest = " + deepest30);  //@var=_,!21            }  //@var=_,!22            // deepest is gone here  //@var=_,!23        }24        25        // inner is no longer accessible here!26        System.out.println("After block: outer = " + outer10);27        // System.out.println(inner);  // Error: cannot find symbol28        29        System.out.println("\n=== Scope Rule ===");  //?rule30        System.out.println("Variables exist only in their { } block");31        System.out.println("Inner blocks can see outer variables");32        System.out.println("Outer blocks cannot see inner variables");33    }
    output=== Block Scope ===
    outer = 10
      In block: outer = 10
      In block: inner = 20
        Deepest: outer = 10
        Deepest: inner = 20
        Deepest: deepest = 30
    After block: outer = 10
    
    === Scope Rule ===
    Variables exist only in their { } block
    Inner blocks can see outer variables
    Outer blocks cannot see inner variables
  1. outer ← 3, inner ← 20, deepest ← 30

    1public class BlockScope {2    public static void main(String[] args) {3        System.out.println("=== Block Scope ===\n");4        5        int outer→ 3 = 3;6        System.out.println("outer = " + outer3);7        8        {9            // Inner block - can see outer10            int inner→ 20 = 20;11            System.out.println("  In block: outer = " + outer3);12            System.out.println("  In block: inner = " + inner20);13            14            // Nested block15            {16                int deepest→ 30 = 30;17                System.out.println("    Deepest: outer = " + outer3);18                System.out.println("    Deepest: inner = " + inner20);19                System.out.println("    Deepest: deepest = " + deepest30);20            }21            // deepest is gone here22        }23        24        // inner is no longer accessible here!25        System.out.println("After block: outer = " + outer3);26        // System.out.println(inner);  // Error: cannot find symbol27        28        System.out.println("\n=== Scope Rule ===");29        System.out.println("Variables exist only in their { } block");30        System.out.println("Inner blocks can see outer variables");31        System.out.println("Outer blocks cannot see inner variables");32    }
    output=== Block Scope ===
    outer = 3
      In block: outer = 3
      In block: inner = 20
        Deepest: outer = 3
        Deepest: inner = 20
        Deepest: deepest = 30
    After block: outer = 3
    
    === Scope Rule ===
    Variables exist only in their { } block
    Inner blocks can see outer variables
    Outer blocks cannot see inner variables
  1. outer ← 42, inner ← 20, deepest ← 30

    1public class BlockScope {2    public static void main(String[] args) {3        System.out.println("=== Block Scope ===\n");4        5        int outer→ 42 = 42;6        System.out.println("outer = " + outer42);7        8        {9            // Inner block - can see outer10            int inner→ 20 = 20;11            System.out.println("  In block: outer = " + outer42);12            System.out.println("  In block: inner = " + inner20);13            14            // Nested block15            {16                int deepest→ 30 = 30;17                System.out.println("    Deepest: outer = " + outer42);18                System.out.println("    Deepest: inner = " + inner20);19                System.out.println("    Deepest: deepest = " + deepest30);20            }21            // deepest is gone here22        }23        24        // inner is no longer accessible here!25        System.out.println("After block: outer = " + outer42);26        // System.out.println(inner);  // Error: cannot find symbol27        28        System.out.println("\n=== Scope Rule ===");29        System.out.println("Variables exist only in their { } block");30        System.out.println("Inner blocks can see outer variables");31        System.out.println("Outer blocks cannot see inner variables");32    }
    output=== Block Scope ===
    outer = 42
      In block: outer = 42
      In block: inner = 20
        Deepest: outer = 42
        Deepest: inner = 20
        Deepest: deepest = 30
    After block: outer = 42
    
    === Scope Rule ===
    Variables exist only in their { } block
    Inner blocks can see outer variables
    Outer blocks cannot see inner variables
  1. outer ← 10, inner ← 5, deepest ← 30

    1public class BlockScope {2    public static void main(String[] args) {3        System.out.println("=== Block Scope ===\n");4        5        int outer→ 10 = 10;6        System.out.println("outer = " + outer10);7        8        {9            // Inner block - can see outer10            int inner→ 5 = 5;11            System.out.println("  In block: outer = " + outer10);12            System.out.println("  In block: inner = " + inner5);13            14            // Nested block15            {16                int deepest→ 30 = 30;17                System.out.println("    Deepest: outer = " + outer10);18                System.out.println("    Deepest: inner = " + inner5);19                System.out.println("    Deepest: deepest = " + deepest30);20            }21            // deepest is gone here22        }23        24        // inner is no longer accessible here!25        System.out.println("After block: outer = " + outer10);26        // System.out.println(inner);  // Error: cannot find symbol27        28        System.out.println("\n=== Scope Rule ===");29        System.out.println("Variables exist only in their { } block");30        System.out.println("Inner blocks can see outer variables");31        System.out.println("Outer blocks cannot see inner variables");32    }
    output=== Block Scope ===
    outer = 10
      In block: outer = 10
      In block: inner = 5
        Deepest: outer = 10
        Deepest: inner = 5
        Deepest: deepest = 30
    After block: outer = 10
    
    === Scope Rule ===
    Variables exist only in their { } block
    Inner blocks can see outer variables
    Outer blocks cannot see inner variables
  1. outer ← 10, inner ← 100, deepest ← 30

    1public class BlockScope {2    public static void main(String[] args) {3        System.out.println("=== Block Scope ===\n");4        5        int outer→ 10 = 10;6        System.out.println("outer = " + outer10);7        8        {9            // Inner block - can see outer10            int inner→ 100 = 100;11            System.out.println("  In block: outer = " + outer10);12            System.out.println("  In block: inner = " + inner100);13            14            // Nested block15            {16                int deepest→ 30 = 30;17                System.out.println("    Deepest: outer = " + outer10);18                System.out.println("    Deepest: inner = " + inner100);19                System.out.println("    Deepest: deepest = " + deepest30);20            }21            // deepest is gone here22        }23        24        // inner is no longer accessible here!25        System.out.println("After block: outer = " + outer10);26        // System.out.println(inner);  // Error: cannot find symbol27        28        System.out.println("\n=== Scope Rule ===");29        System.out.println("Variables exist only in their { } block");30        System.out.println("Inner blocks can see outer variables");31        System.out.println("Outer blocks cannot see inner variables");32    }
    output=== Block Scope ===
    outer = 10
      In block: outer = 10
      In block: inner = 100
        Deepest: outer = 10
        Deepest: inner = 100
        Deepest: deepest = 30
    After block: outer = 10
    
    === Scope Rule ===
    Variables exist only in their { } block
    Inner blocks can see outer variables
    Outer blocks cannot see inner variables

Variables declared inside {} are not visible outside those braces.

block scope Variable visibility limited to the `{}` block where it's declared.

Variable shadowing

Inner variables can hide outer variables with the same name.

Shadowing.java
Replay: real traced execution (multi-file project)
public class Shadowing {
    static int x = 100;  // Class-level x

    public static void main(String[] args) {
        System.out.println("=== Variable Shadowing ===\n");

        System.out.println("Class-level x = " + x);  // 100

        int x = 50;  // Local x shadows class x
        System.out.println("Local x = " + x);  // 50

        System.out.println("Class x via class name = " + Shadowing.x);

        {
            int y = x + 10;  // Uses local x (50)
            System.out.println("Inner block uses local x: y = " + y);

            // Cannot re-declare x in inner scope in Java!
            // int x = 25;  // Error: x already defined
        }

        // Method parameter shadowing
        System.out.println("\n=== Method Parameter Shadowing ===");
        processValue(999);
        System.out.println("After method: x = " + x);  // Still 50

        System.out.println("\n=== Shadowing Summary ===");
        System.out.println("Inner variables can hide outer ones");
        System.out.println("Use class name to access shadowed static variables");
    }

    static void processValue(int x) {  // Parameter shadows local
        System.out.println("In method, parameter x = " + x);  // 999
        System.out.println("Class x = " + Shadowing.x);  // 100
    }
}
  1. x ← 50, y ← 60

    5public static void main(String[] args) {6    System.out.println("=== Variable Shadowing ===\n");7    8    System.out.println("Class-level x = " + x100);  // 1009    10    int x→ 50 = 50;  // Local x shadows class x  //?shadow11    System.out.println("Local x = " + x50);  // 5012    13    System.out.println("Class x via class name = " + Shadowing.x);  //?access14    15    {16        int y→ 60 = x50 + 10;  // Uses local x (50)17        System.out.println("Inner block uses local x: y = " + y60);18        19        // Cannot re-declare x in inner scope in Java!20        // int x = 25;  // Error: x already defined21    }22    23    // Method parameter shadowing  //@var=_,!24    System.out.println("\n=== Method Parameter Shadowing ===");  //@var=_,!25    processValue(999);  //@var=_,!26    System.out.println("After method: x = " + x);  // Still 50  //@var=_,!
    output=== Variable Shadowing ===
    Class-level x = 100
    Local x = 50
    Class x via class name = 100
    Inner block uses local x: y = 60
    
    === Method Parameter Shadowing ===
  2. static void processValue(int x)

    24    System.out.println("\n=== Method Parameter Shadowing ===");  //@var=_,!25    processValue(999);  //@var=_,!26    System.out.println("After method: x = " + x50);  // Still 50  //@var=_,!27    28    System.out.println("\n=== Shadowing Summary ===");29    System.out.println("Inner variables can hide outer ones");30    System.out.println("Use class name to access shadowed static variables");31}3233//@var=_,!34static void processValue(int x999) {  // Parameter shadows local35    System.out.println("In method, parameter x = " + x999);  // 99936    System.out.println("Class x = " + Shadowing.x);  // 10037}
    outputIn method, parameter x = 999
    Class x = 100
    After method: x = 50
    
    === Shadowing Summary ===
    Inner variables can hide outer ones
    Use class name to access shadowed static variables

A local variable with the same name as a field "shadows" the field.

shadowing Inner variable hides outer variable of same name. Use `this.field` to access hidden field.

Loop variable scope

Loop variables are scoped to the loop block.

LoopScope.java
Replay: real traced execution (multi-file project)
public class LoopScope {
    public static void main(String[] args) {
        System.out.println("=== Loop Variable Scope ===\n");

        // For loop variable
        System.out.println("For loop:");
        for (int i = 0; i < 3; i++) {
            System.out.println("  i = " + i);
        }
        // System.out.println(i);  // Error: i not accessible

        // Variable declared outside loop
        System.out.println("\nVariable outside loop:");
        int sum = 0;
        for (int j = 1; j <= 5; j++) {
            sum += j;
            System.out.println("  j=" + j + ", sum=" + sum);
        }
        System.out.println("Final sum = " + sum);  // sum still accessible

        // Each iteration creates new local
        System.out.println("\nNew variable each iteration:");
        for (int k = 0; k < 3; k++) {
            int temp = k * 10;  // Created fresh each iteration
            System.out.println("  k=" + k + ", temp=" + temp);
        }  // temp dies here, k dies here

        // While loop scope
        System.out.println("\nWhile loop:");
        int count = 0;  // Must declare outside
        while (count < 3) {
            int local = count * 2;  // New each iteration
            System.out.println("  count=" + count + ", local=" + local);
            count++;
        }  // local dies, count survives
        System.out.println("Final count = " + count);
    }
}
  1. public static void main(String[] args)

    1public class LoopScope {2    public static void main(String[] args) {3        System.out.println("=== Loop Variable Scope ===\n");4        5        // For loop variable  //?forloop6        System.out.println("For loop:");7        for (int i = 0; i < 3; i++) {
    output=== Loop Variable Scope ===
    For loop:
  2. for (int i = 0; i < 3; i++)

    pass 1 of 3
    6System.out.println("For loop:");7for (int i0 = 0; i < 3; i++) {8    System.out.println("  i = " + i0);9}
    output  i = 0
    All 3 passes — pass 1 is the card above
    passi
    10
    21
    32
  3. sum ← 0

    12// Variable declared outside loop  //?outside13System.out.println("\nVariable outside loop:");14int sum→ 0 = 0;15for (int j = 1; j <= 5; j++) {
    output
    Variable outside loop:
  4. sum ← 1

    pass 1 of 5
    14int sum = 0;15for (int j1 = 1; j <= 5; j++) {16    sum→ 1 += j1;17    System.out.println("  j=" + j1 + ", sum=" + sum1);18}
    output  j=1, sum=1
    All 5 passes — pass 1 is the card above
    passjsum
    110 1
    221 3
    333 6
    446 10
    5510 15
  5. System.out.println("Final sum = " + sum); // sum still accessible

    18}19System.out.println("Final sum = " + sum15);  // sum still accessible2021// Each iteration creates new local  //?newvar22System.out.println("\nNew variable each iteration:");23for (int k = 0; k < 3; k++) {
    outputFinal sum = 15
    
    New variable each iteration:
  6. temp ← 0

    pass 1 of 3
    22System.out.println("\nNew variable each iteration:");23for (int k0 = 0; k < 3; k++) {24    int temp→ 0 = k0 * 10;  // Created fresh each iteration25    System.out.println("  k=" + k0 + ", temp=" + temp0);26}  // temp dies here, k dies here
    output  k=0, temp=0
    All 3 passes — pass 1 is the card above
    passktemp
    100
    2110
    3220
  7. count ← 0

    28// While loop scope  //?while29System.out.println("\nWhile loop:");30int count→ 0 = 0;  // Must declare outside31while (count < 3) {
    output
    While loop:
  8. local ← 0, count ← 1

    pass 1 of 3
    30int count = 0;  // Must declare outside31while (count0 < 3) {32    int local→ 0 = count0 * 2;  // New each iteration33    System.out.println("  count=" + count0 + ", local=" + local0);34    count→ 1++;35}  // local dies, count survives
    output  count=0, local=0
    All 3 passes — pass 1 is the card above
    passlocalcount
    100 1
    221 2
    342 3
  9. System.out.println("Final count = " + count);

    35    }  // local dies, count survives36    System.out.println("Final count = " + count3);37}
    outputFinal count = 3

The i in for (int i ...) only exists inside the loop body.

Method parameter scope

Parameters are local to the method.

MethodScope.java
Replay: real traced execution (multi-file project)
public class MethodScope {
    public static void main(String[] args) {
        System.out.println("=== Method Scope ===\n");

        int result = calculate(10, 5);
        System.out.println("Result: " + result);

        // Cannot access a, b, sum from here!
        // System.out.println(a);  // Error!

        System.out.println("\n=== Multiple Calls ===");
        System.out.println("calculate(20, 3) = " + calculate(20, 3));
        System.out.println("calculate(7, 8) = " + calculate(7, 8));

        // Each call has independent variables
        System.out.println("\n=== Lifetime Demo ===");
        trackLifetime();
        trackLifetime();  // Same variable names, fresh values
    }

    static int calculate(int a, int b) {
        // a and b are parameters - local to this method
        System.out.println("  In calculate: a=" + a + ", b=" + b);

        int sum = a + b;
        int product = a * b;

        System.out.println("  sum=" + sum + ", product=" + product);

        return sum;  // After return, a, b, sum, product all die
    }

    static int callCount = 0;  // Class variable - persists

    static void trackLifetime() {
        callCount++;  // Persists across calls
        int localCounter = 1;  // Dies after method ends

        System.out.println("Call #" + callCount +
                          ", localCounter=" + localCounter);
    }
}
  1. public static void main(String[] args)

    1public class MethodScope {2    public static void main(String[] args) {3        System.out.println("=== Method Scope ===\n");4        5        int result = calculate(10, 5);  //?call6        System.out.println("Result: " + result);
    output=== Method Scope ===
  2. sum ← 15, product ← 50

    pass 1 of 3
    21static int calculate(int a10, int b5) {  //?params22    // a and b are parameters - local to this method23    System.out.println("  In calculate: a=" + a10 + ", b=" + b5);24    25    int sum→ 15 = a10 + b5;  //?local26    int product→ 50 = a10 * b5;27    28    System.out.println("  sum=" + sum15 + ", product=" + product50);29    30    return sum15;  // After return, a, b, sum, product all die31}
    output  In calculate: a=10, b=5
      sum=15, product=50
    All 3 passes — pass 1 is the card above
    passabsumproduct
    11051550
    22032360
    3781556
  3. result ← 15

    5int result→ 15 = calculate(10, 5);  //?call6System.out.println("Result: " + result15);78// Cannot access a, b, sum from here!9// System.out.println(a);  // Error!1011System.out.println("\n=== Multiple Calls ===");12System.out.println("calculate(20, 3) = " + calculate(20, 3));13System.out.println("calculate(7, 8) = " + calculate(7, 8));
    outputResult: 15
    
    === Multiple Calls ===
  4. System.out.println("calculate(20, 3) = " + calculate(20, 3));

    11System.out.println("\n=== Multiple Calls ===");12System.out.println("calculate(20, 3) = " + calculate(20, 3));13System.out.println("calculate(7, 8) = " + calculate(7, 8));
    outputcalculate(20, 3) = 23
  5. System.out.println("calculate(7, 8) = " + calculate(7, 8));

    12System.out.println("calculate(20, 3) = " + calculate(20, 3));13System.out.println("calculate(7, 8) = " + calculate(7, 8));1415// Each call has independent variables16System.out.println("\n=== Lifetime Demo ===");17trackLifetime();18trackLifetime();  // Same variable names, fresh values
    outputcalculate(7, 8) = 15
    
    === Lifetime Demo ===
  6. callCount ← 1, localCounter ← 1

    pass 1 of 2
    16    System.out.println("\n=== Lifetime Demo ===");17    trackLifetime();18    trackLifetime();  // Same variable names, fresh values19}2021static int calculate(int a, int b) {  //?params22    // a and b are parameters - local to this method23    System.out.println("  In calculate: a=" + a + ", b=" + b);24    25    int sum = a + b;  //?local26    int product = a * b;27    28    System.out.println("  sum=" + sum + ", product=" + product);29    30    return sum;  // After return, a, b, sum, product all die31}3233static int callCount = 0;  // Class variable - persists  //?persist3435static void trackLifetime() {36    callCount→ 1++;  // Persists across calls37    int localCounter→ 1 = 1;  // Dies after method ends38    39    System.out.println("Call #" + callCount1 + 40                      ", localCounter=" + localCounter1);41}
    outputCall #1, localCounter=1
  7. callCount ← 2, localCounter ← 1

    pass 2 of 2
    17    trackLifetime();18    trackLifetime();  // Same variable names, fresh values19}2021static int calculate(int a, int b) {  //?params22    // a and b are parameters - local to this method23    System.out.println("  In calculate: a=" + a + ", b=" + b);24    25    int sum = a + b;  //?local26    int product = a * b;27    28    System.out.println("  sum=" + sum + ", product=" + product);29    30    return sum;  // After return, a, b, sum, product all die31}3233static int callCount = 0;  // Class variable - persists  //?persist3435static void trackLifetime() {36    callCount→ 2++;  // Persists across calls37    int localCounter→ 1 = 1;  // Dies after method ends38    39    System.out.println("Call #" + callCount2 + 40                      ", localCounter=" + localCounter1);41}
    outputCall #2, localCounter=1

Parameters act like local variables, existing only during method execution.

Instance vs local variables

Distinguish between object fields and method-local variables.

InstanceVsLocal.java
Replay: real traced execution (multi-file project)
public class InstanceVsLocal {
    public static void main(String[] args) {
        System.out.println("=== Instance vs Local Variables ===\n");

        Counter c1 = new Counter("Counter-A");
        Counter c2 = new Counter("Counter-B");

        c1.increment();
        c1.increment();
        c1.increment();

        c2.increment();

        System.out.println("\n=== Final State ===");
        c1.showCount();
        c2.showCount();

        System.out.println("\n=== Key Difference ===");
        System.out.println("Instance vars: belong to object, persist");
        System.out.println("Local vars: belong to method call, temporary");
    }
}

class Counter {
    // Instance variable - each Counter has its own
    String name;
    int count = 0;

    Counter(String name) {
        this.name = name;
    }

    void increment() {
        int oldCount = count;
        count++;
        System.out.println(name + ": " + oldCount + " → " + count);
    }

    void showCount() {
        System.out.println(name + " final count: " + count);
    }
}
  1. public static void main(String[] args)

    1public class InstanceVsLocal {2    public static void main(String[] args) {3        System.out.println("=== Instance vs Local Variables ===\n");4        5        Counter c1 = new Counter("Counter-A");  //?create6        Counter c2 = new Counter("Counter-B");
    output=== Instance vs Local Variables ===
  2. this.name ← Counter-A, c1 ← ⟨Counter A⟩

    pass 1 of 2
    5        Counter c1→ ⟨Counter A⟩ = new Counter("Counter-A");  //?create6        Counter c2 = new Counter("Counter-B");7        8        c1.increment();  //?ops9        c1.increment();10        c1.increment();11        12        c2.increment();13        14        System.out.println("\n=== Final State ===");15        c1.showCount();16        c2.showCount();17        18        System.out.println("\n=== Key Difference ===");19        System.out.println("Instance vars: belong to object, persist");20        System.out.println("Local vars: belong to method call, temporary");21    }22}2324class Counter {25    // Instance variable - each Counter has its own  //?instance26    String name;27    int count = 0;28    29    Counter(String nameCounter-A) {30        this.name→ Counter-A = nameCounter-A;  //?this31    }
  3. this.name ← Counter-B, c2 ← ⟨Counter B⟩

    pass 2 of 2
    5        Counter c1 = new Counter("Counter-A");  //?create6        Counter c2→ ⟨Counter B⟩ = new Counter("Counter-B");7        8        c1.increment();  //?ops9        c1.increment();10        c1.increment();11        12        c2.increment();13        14        System.out.println("\n=== Final State ===");15        c1.showCount();16        c2.showCount();17        18        System.out.println("\n=== Key Difference ===");19        System.out.println("Instance vars: belong to object, persist");20        System.out.println("Local vars: belong to method call, temporary");21    }22}2324class Counter {25    // Instance variable - each Counter has its own  //?instance26    String name;27    int count = 0;28    29    Counter(String nameCounter-B) {30        this.name→ Counter-B = nameCounter-B;  //?this31    }
  4. oldCount ← 0, count ← 1

    pass 1 of 4
    8        c1.increment();  //?ops9        c1.increment();10        c1.increment();11        12        c2.increment();13        14        System.out.println("\n=== Final State ===");15        c1.showCount();16        c2.showCount();17        18        System.out.println("\n=== Key Difference ===");19        System.out.println("Instance vars: belong to object, persist");20        System.out.println("Local vars: belong to method call, temporary");21    }22}2324class Counter {25    // Instance variable - each Counter has its own  //?instance26    String name;27    int count = 0;28    29    Counter(String name) {30        this.name = name;  //?this31    }32    33    void increment() {34        int oldCount→ 0 = count;  //?localvar35        count→ 1++;36        System.out.println(nameCounter-A + ": " + oldCount0 + " → " + count1);37    }
    outputCounter-A: 0 → 1
    All 4 passes — pass 1 is the card above
    passnameoldCountcount
    1Counter-A00 1
    2Counter-A11 2
    3Counter-A22 3
    4Counter-B00 1
  5. void showCount()

    pass 1 of 2
    14        System.out.println("\n=== Final State ===");15        c1.showCount();16        c2.showCount();17        18        System.out.println("\n=== Key Difference ===");19        System.out.println("Instance vars: belong to object, persist");20        System.out.println("Local vars: belong to method call, temporary");21    }22}2324class Counter {25    // Instance variable - each Counter has its own  //?instance26    String name;27    int count = 0;28    29    Counter(String name) {30        this.name = name;  //?this31    }32    33    void increment() {34        int oldCount = count;  //?localvar35        count++;36        System.out.println(name + ": " + oldCount + " → " + count);37    }38    39    void showCount() {40        System.out.println(nameCounter-A + " final count: " + count3);41    }
    outputCounter-A final count: 3
  6. void showCount()

    pass 2 of 2
    15        c1.showCount();16        c2.showCount();17        18        System.out.println("\n=== Key Difference ===");19        System.out.println("Instance vars: belong to object, persist");20        System.out.println("Local vars: belong to method call, temporary");21    }22}2324class Counter {25    // Instance variable - each Counter has its own  //?instance26    String name;27    int count = 0;28    29    Counter(String name) {30        this.name = name;  //?this31    }32    33    void increment() {34        int oldCount = count;  //?localvar35        count++;36        System.out.println(name + ": " + oldCount + " → " + count);37    }38    39    void showCount() {40        System.out.println(nameCounter-B + " final count: " + count1);41    }
    outputCounter-B final count: 1
    
    === Key Difference ===
    Instance vars: belong to object, persist
    Local vars: belong to method call, temporary

Instance variables live with the object. Local variables die when the method returns.

instance variable Field that belongs to object, exists for object's lifetime.

Exercise: ClosureLambda.java

Explore effectively final and lambda variable capture