1. 概述

在 Java(以及大多数编程语言)中,每个变量都有其作用域(Scope)。所谓作用域,就是变量可以被访问和使用的代码范围。

本文将介绍 Java 中常见的几种变量作用域,并说明它们之间的区别。

2. 类作用域(Class Scope)

定义在类的大括号 {} 内、方法之外,并使用 private 修饰符声明的变量,属于类作用域。这类变量在整个类内部都可以访问,但在类外部无法直接访问:

public class ClassScopeExample {
    private Integer amount = 0;
    public void exampleMethod() {
        amount++;
    }
    public void anotherExampleMethod() {
        Integer anotherAmount = amount + 4;
    }
}

在这个例子中,amount 是一个类级别的变量,在类的所有方法中都可以使用。

⚠️ 如果不使用 private,而是默认的包访问权限(package-private),那么该变量在同一个包中的其他类也可以访问。关于访问修饰符的详细内容,可以参考这篇文章

3. 方法作用域(Method Scope)

在方法内部声明的变量,具有方法作用域,只能在该方法内部使用:

public class MethodScopeExample {
    public void methodA() {
        Integer area = 2;
    }
    public void methodB() {
        // 编译错误:找不到变量 area
        area = area + 2;
    }
}

✅ 在 methodA 中定义的变量 area 只能在该方法中使用,其他方法无法访问。

4. 循环作用域(Loop Scope)

在循环结构中声明的变量,具有循环作用域,仅能在该循环体内访问:

public class LoopScopeExample {
    List<String> listOfNames = Arrays.asList("Joe", "Susan", "Pattrick");
    public void iterationOfNames() {
        String allNames = "";
        for (String name : listOfNames) {
            allNames = allNames + " " + name;
        }
        // 编译错误:name 无法解析为变量
        String lastNameUsed = name;
    }
}

❌ 变量 name 只能在 for 循环内部使用,循环外部是无法访问的。

5. 块作用域(Bracket Scope)

我们还可以通过 {} 显式地定义一个新的作用域块,这叫做块作用域

public class BracketScopeExample {    
    public void mathOperationExample() {
        Integer sum = 0;
        {
            Integer number = 2;
            sum = sum + number;
        }
        // 编译错误:无法识别变量 number
        number++;
    }
}

number 只能在它所在的那对大括号内使用。

6. 作用域与变量遮蔽(Variable Shadowing)

当我们在方法中声明了一个与类变量同名的局部变量时,会发生变量遮蔽(Variable Shadowing)现象:

public class NestedScopesExample {
    String title = "Baeldung";
    public void printTitle() {
        System.out.println(title); // 输出 "Baeldung"
        String title = "John Doe";
        System.out.println(title); // 输出 "John Doe"
    }
}

第一次打印时输出的是类变量 title 的值 "Baeldung",但一旦在方法中重新定义了名为 title 的局部变量,后续对该名称的引用都会指向这个局部变量。

⚠️ 这种写法容易引起混淆,是一种不良实践。推荐使用 this.title 来明确访问类变量:

System.out.println(this.title); // 明确输出类变量

7. 总结

我们介绍了 Java 中常见的几种变量作用域:

  • 类作用域
  • 方法作用域
  • 循环作用域
  • 块作用域

同时也讨论了变量遮蔽的问题,以及如何避免它带来的潜在风险。

📌 完整代码示例可以在 GitHub 上找到。


原始标题:Variable Scope in Java | Baeldung