Unit 3.8: Scope and Access
Scope refers to the region of a program where a variable is accessible.
- Scope is the "territory" of a variable. A variable is only "visible" and available for use within the specific block of code
{ }where it was declared.
In Java, a variable's scope is strictly defined by where it is declared. Understanding scope is critical for avoiding bugs and ensuring that data is only manipulated where intended.
You first encountered the concept of variable categories and their basic visibility rules in the Types of Variables lesson. In this section, we will delve deeper into the specific rules governing local scope and the implications of naming conflicts.
Local Variables
Local variables are variables declared in the headers or bodies of blocks of code (typically within curly braces { }).
- Access Limitation: Local variables can only be accessed within the specific block in which they are declared.
- Constructors and Methods: Since these are distinct blocks of code, any variable created inside them—including parameters—is considered local to that method or constructor.
- Lifetime: These variables are created when the block is entered and "destroyed" (removed from memory) when the block finishes executing.
- Restriction on Access Modifiers: Local variables cannot be declared as
publicorprivate. Attempting to do so will result in a compile-time error.
Example: Block Scope
public class ScopeDemo {
public void calculate(int limit) {
int total = 0; // Local to calculate method
for (int i = 0; i < limit; i++) {
int temp = i * 2; // Local to the for-loop block
total += temp;
}
// System.out.println(temp); // COMPILE ERROR: temp is out of scope
System.out.println(total); // OK: total is still in scope
}
}
Example: Constructor and Method Scope
A common mistake is trying to use a constructor parameter or a local variable inside a different method.
Task: Identifying scope isolation between methods and constructors.
public class Vault {
private int balance;
public Vault(int initialDeposit) {
// 'initialDeposit' is a local parameter
// 'bonus' is a local variable
int bonus = 50;
balance = initialDeposit + bonus;
}
public void checkSecurity() {
System.out.println("Balance is: " + balance); // OK: balance is instance variable
// System.out.println(bonus); // COMPILE ERROR: bonus is local to Vault()
// System.out.println(initialDeposit); // COMPILE ERROR: initialDeposit is local to Vault()
}
}
Variable Shadowing
A common point of confusion occurs when a local variable or parameter has the exact same name as an instance variable.
- When a local variable has the same name as an instance variable, the local one takes precedence. The instance variable is still there, but it is "shadowed" and cannot be accessed by its simple name alone.
This is known as shadowing.
- The Rule of Precedence: Within the body of the method or constructor, the variable name will always refer to the local variable (or parameter) instead of the instance variable.
- Implication: The instance variable becomes "hidden" or shadowed by the local one. If you intend to update the instance variable but forget this rule, your program may not behave as expected.
Task: Identifying a logic error caused by variable shadowing.
public class Player {
private int health = 100;
public void heal(int health) {
// This line updates the PARAMETER 'health', not the instance variable!
health = health + 10;
System.out.println("Local health: " + health);
}
}
Common Scope Pitfalls
When analyzing code, watch out for these common "out of scope" errors:
1. Loop Variable Access
Trying to use a loop control variable after the loop has finished will cause a compile-time error.
Task: Identifying a compile error from accessing a loop variable out of scope.
for (int i = 0; i < 5; i++) {
System.out.print(i);
}
// System.out.println(i); // COMPILE ERROR: i is out of scope here
2. Conditional Initialization
Declaring a variable inside an if block and trying to use it in the else block or after the if/else structure is a common mistake.
Task: Identifying a compile error from accessing a conditionally declared variable.
if (score > 90) {
String grade = "A";
} else {
// System.out.println(grade); // COMPILE ERROR: grade only exists in 'if' block
String grade = "B";
}
// System.out.println(grade); // COMPILE ERROR: grade is out of scope here
3. Shadowing Confusion
Assuming an instance variable was updated when a local variable of the same name was actually the one modified.
Task: Tracing a shadowing logic error.
public class Tracker {
private int count = 0;
public void add(int count) {
// This updates the PARAMETER count, not the instance variable!
count = count + 1;
}
}
Note: In the next section (Topic 3.9), we will explore how the
thiskeyword allows us to explicitly reference instance variables even when they are being shadowed by local ones. See Unit 3.9: this Keyword.