3.8 - Scope and Access
A local variable is one declared inside the header or body of a block of code, and it can only be used within that same block. Since constructors and methods are both blocks of code, their parameters count as local variables too. Local variables and parameters can never be declared
public or private, that only applies to instance variables, class variables, and methods.public void exampleMethod(int x) { // x is a local variable (parameter) int y = 10; // y is also a local variable // both x and y only exist inside this method }
A block is any code inside braces
{ }, so a variable declared inside an if statement or a loop (including a for loop’s header) only exists inside that if or loop. Instance variables are different: every method and constructor in the class can use them.public void scopeDemo(int x) { if (x > 0) { int bonus = 5; // bonus only exists inside this if block x += bonus; } for (int i = 0; i < 3; i++) { // i only exists inside this loop x++; } System.out.println(x); // fine: x can be used anywhere in this method System.out.println(bonus); // compile error: bonus is out of scope here System.out.println(i); // compile error: i is out of scope here } public void otherMethod() { private int z = 4; // compile error: a local variable can't be private System.out.println(x); // compile error: x only exists inside scopeDemo }
If a local variable or parameter happens to share a name with an instance variable, then inside that method or constructor, using that name refers to the local one, not the instance variable. This is called shadowing.
public class Dog { private String name; public Dog(String name) { // parameter "name" shadows the instance variable name = name; // this does nothing useful, just assigns the parameter to itself! } }
So a
Dog made with this constructor still has a name of null, because the constructor never touched the instance variable. There are two ways to fix it: give the parameter a different name, or use the keyword this (see 3.9).// Fix 1: a different parameter name, so nothing is shadowed public Dog(String n) { name = n; } // Fix 2: this.name always means the instance variable public Dog(String name) { this.name = name; }
Shadowing also happens with a local variable declared inside a method:
public class Dog { private int age; public Dog(int a) { age = a; } public void printAge() { int age = 10; // local variable with the same name as the instance variable System.out.println(age); // uses the local age } } Dog d = new Dog(3); d.printAge(); // prints 10, not 3