为什么在java中对于方法之外的变量有一个重复的变量名?

时间:2016-02-07 02:10:09

标签: java

我正在学习Java,我理解你不能将在内部作用域内声明的变量命名为与在外部作用域中声明的变量相同的名称,如下所示

public class Practice {
public static void main(String []args){
    int x=10;
    if (x==10){
        int x=10;
        }           
    }   
}

但是,我注意到这不是非法的

public class Practice {
int x=10;
public static void main(String []args){
    int x=10;
    if (x==10){
        }           
    }   
}

这不是一个声明两次的变量吗?

4 个答案:

答案 0 :(得分:3)

  

这不是一个声明两次的变量吗?

不,不是。因为它们都在不同的范围内。 x函数之外的main具有类级别范围,而x内的main具有方法/函数级别范围

不同范围内的2个变量具有相同名称是合法的。

请从JLS阅读§6.3. Scope of a Declaration。以下是该部分的一些陈述。

  

声明的范围是程序的范围   声明声明的实体可以使用a来引用   简单名称,只要它是可见的(§6.4.1)。

     

声称声明属于a中特定点的范围   当且仅当声明的范围包括该点时才编程。

     

块(第14.4节)中局部变量声明的范围是   声明出现的块的其余部分,从其开始   拥有初始化程序,并包括右边的任何进一步的声明符   局部变量声明语句。

有许多与阴影等范围相关的概念,请阅读§6.4. Shadowing and Obscuring

JLS是了解Java中允许的内容和不允许的内容的最佳位置。随意阅读那里的部分。

答案 1 :(得分:1)

在第二种情况下,在方法之外声明x时,它是类Practice的实例变量。在该方法中,x(在main内声明)的范围仅限于main方法。

在第一种情况下,当您在方法中声明x时,您无法在if内声明它,因为它已在if之外的方法范围内声明。

答案 2 :(得分:1)

第一个代码片段显示变量在方法的范围内。所以两个变量属于同一个不允许的方法。

但是在第二个例子中,一个变量在实例级别而另一个在方法的范围内,因此没有重复。在第二个示例中,如果要访问实例变量,则必须使用this.x。

在此处查看有关变量范围和生命周期的更多信息

http://www.javawithus.com/tutorial/scope-and-lifetime-of-variables

答案 3 :(得分:0)

  

为什么在java中对于方法之外的变量有重复的变量名?

它不是非法的,因为Java语言规范允许它。 (是......循环解释)

与所有这些问题一样,我们无法确定为什么是允许的,因为Java语言是闭门设计的。但是,有几个可能的原因是:

  • Java最初的目的是让人感到愉快。对于C和C ++程序员来说,这是一个不同的做法(禁止阴影)会导致异议的情况。

  • 很多人实际上都喜欢它们,他们不必为变量考虑不同的名称; e.g。

     public class Foo {
         private Bar bar;
    
         public Foo() {
            Bar bar = new Bar();
            this.bar = bar;
         }
     }
    

不可否认,存在不利因素。有时,人们错误地声明影响实例(或静态)变量的局部变量。特别是新手: - )

  

这不是一个声明两次的变量吗?

没有。它实际上是两个>> distinct<<变量。两者都存在。在该方法中,x 的本地声明 x的实例声明。但你仍然可以将后者称为this.x