📜  Java中的变量范围

📅  最后修改于: 2020-02-12 14:58:05             🧑  作者: Mango

变量的范围是程序中可访问变量的部分。像C / C++一样,在Java中,所有标识符都在词法(或静态)范围内,即,变量的范围可以在编译时确定,并且与函数调用堆栈无关。
Java程序以类的形式组织。每个类都是某些程序包的一部分。Java范围规则可以归入以下类别。
成员变量(类级别范围)
这些变量必须在类内部(在任何函数外部)声明。可以在类的任何地方直接访问它们。让我们看一个例子:

public class Test
{
    // 声明成员变量
    int a;
    private String b
    void method1() {....}
    int method2() {....}
    char c;
}
  • 我们可以在类中的任何地方,且在外部方法中声明类变量。
  • 指定的成员变量访问不会影响它们在类中的作用域。
  • 可以使用以下规则在类外部访问成员变量
    Modifier      Package  Subclass  World
    public          Yes      Yes     Yes
    protected       Yes      Yes     No
    Default (no
    modifier)       Yes       No     No
    private         No        No     No

局部变量(方法级别范围)
在方法内部声明的变量具有方法级别范围,不能在方法外部访问。

public class Test
{
    void method1()
    {
       // 局部变量,方法级别范围
       int x;
    }
}

注意:方法执行结束后,局部变量就不存在了。
这是方法范围的另一个示例,除了这次变量是作为参数传递给方法的:

class Test
{
    private int x;
    public void setX(int x)
    {
        this.x = x;
    }
}

上面的代码使用此关键字来区分局部变量和类变量。
作为练习,请预测以下Java程序的输出。

public class Test
{
    static int x = 11;
    private int y = 33;
    public void method1(int x)
    {
        Test t = new Test();
        this.x = 22;
        y = 44;
        System.out.println("Test.x: " + Test.x);
        System.out.println("t.x: " + t.x);
        System.out.println("t.y: " + t.y);
        System.out.println("y: " + y);
    }
    public static void main(String args[])
    {
        Test t = new Test();
        t.method1(5);
    }
}

输出:

Test.x: 22
t.x: 22
t.y: 33
y: 44

循环变量(块作用域)
在方法中的括号“ {“和“}”,是对其中声明的变量的作用域。

public class Test
{
    public static void main(String args[])
    {
        {
            // 变量x的范围在两个花括号内
            int x = 10;
            System.out.println(x);
        }
        // 解注释如下的打印,运行会报错,因为x不再此范围.
        // System.out.println(x);
    }
}

输出:

10

再举一个例子,考虑以下带有for循环的程序。

class Test
{
    public static void main(String args[])
    {
        for (int x = 0; x < 4; x++)
        {
            System.out.println(x);
        }
        // 将报错
        System.out.println(x);
    }
}

输出:

11: error: cannot find symbol
        System.out.println(x);

正确的做法是,

// 纠正了上述的报错
class Test
{
    public static void main(String args[])
    {
        int x;
        for (x = 0; x < 4; x++)
        {
            System.out.println(x);
        }
       System.out.println(x);
    }
}

输出:

0
1
2
3
4

让我们看一下循环范围的棘手示例,请预测以下程序的输出。如果您是普通的C / C++程序员,您可能会感到惊讶。

class Test
{
    public static void main(String args[])
    {
        int a = 5;
        for (int a = 0; a < 5; a++)
        {
            System.out.println(a);
        }
    }
}

输出:

6: error: variable a is already defined in method go(int)
       for (int a = 0; a < 5; a++)
                ^
1 error

注意:在C++中,它将运行。但是在Java中,这是一个错误,因为在Java中,内循环和外循环的变量名称必须不同。
 
作为练习,请预测以下Java程序的输出。

class Test
{
    public static void main(String args[])
    {
        {
            int x = 5;
            {
                int x = 10;
                System.out.println(x);
            }
        }
    }
} 

有关Java中的变量作用域的一些要点:

  • 通常,一组花括号{}定义一个范围。
  • 在Java中,只要在与我们正在编写的代码相同的括号内,或在定义变量的大括号内的任何大括号内定义变量,通常就可以访问该变量。
  • 所有成员方法都可以使用任何方法之外的类中定义的任何变量。
  • 当方法具有与成员相同的局部变量时,此关键字可用于引用当前的类变量。
  • 为了在循环终止后读取变量,必须在循环体之前声明该变量。