为什么此Java代码没有给出“已定义”错误?

时间:2019-10-21 14:56:26

标签: java

为什么此Java代码未给出y的已定义错误? 我能理解原因,因为它是一个循环。但这似乎不合逻辑。

class AlreadyDefined 
{
    public static void main(String[] args)
    {
        //int y = 0; //-- enable this for already defined error 
        for(int i = 0; i < 5; i++) 
        {
            int y = i; //not already defined 
            System.out.println(i);
        }
    }
}

如果我运行此代码,则会导致错误:

class AlreadyDefined 
{
    public static void main(String[] args)
    {
        int y = 0;
        for(int i = 0; i < 5; i++) 
        {
            int y = i; //already defined 
            System.out.println(i);
        }
    }
}

3 个答案:

答案 0 :(得分:0)

因为您两次声明了y。在循环 int y = 0; 之外,在循环 int y = i;

您应该替换int y = i;与y = i; 。这应该可以解决您的问题。

答案 1 :(得分:0)

首先声明的y变量涵盖了更广泛的范围,包括您的for循环块。因此,它在for循环内部已经可见。因此,在for循环中重新定义它会引发编译错误

class AlreadyDefined 
{
public static void main(String[] args)
{
    int y = 0; //this variable is global in aspect to your for loop
    for(int i = 0; i < 5; i++) 
    {
        int y = i; //your y variable is visible in this for loop block
                   //so redefining it would throw a compiler error
        System.out.println(i);
    }
}
}

因此,如果您确实要使用变量y,则无需再次定义它,并在其之前删除int类型。

答案 2 :(得分:0)

简短的回答:您不能在同一范围内两次定义相同的变量。 for循环的范围发生在方法的范围内,因此y已经定义。

长答案:这是对可变范围的误解。我会尝试解释:

class AlreadyDefined // begin class scope
{

    public static void main(String[] args){ // begin method scope

        for(int i = 0; i < 5; i++){ // begin loop scope. 
            /// This scope also includes variables from method scope
            int y = i; 
            System.out.println(i);
        } // end loop scope

    } // end method scope

} // end class scope

我在上面的代码中标记了各个范围以及它们的开始和结束位置。

在上面的示例中,for循环结束后,int y超出了范围,无法再被引用。因此,end loop scope之后,System.out.println(y)将失败,因为y不再存在。

在第二个示例中,y已存在于方法范围内。您不能在“子”范围内重新定义具有相同名称的变量,这就是第二个示例失败的原因。

但是,有一个例外。您可以定义一个与类范围中定义的变量名称相同的变量。这样就可以了:

class AlreadyDefined // begin class scope
{
    static int y = 0; // Defining variable with identical name.

    public static void main(String[] args){ // begin method scope

        for(int i = 0; i < 5; i++){ // begin loop scope
            int y = i; // This still works
            System.out.println(i);
        } // end loop scope

    } // end method scope

} // end class scope

对于类范围,如果方法范围中存在一个同名变量,则必须使用this对其进行限定。因此,要引用y中的类作用域main变量,可以使用this.y。这就是为什么您通常会看到在构造函数和setter中分配的变量是这样的原因:

public class SomeClass {
    int property

    public SomeClass(int property) {
        this.property = property;
    }

    public void setProperty(int property) {
        this.property = property;
    }
}

另一个例子:

    public void setProperty(int property) {
       property = property;
    }

如果要执行此操作,则不会生效,因为您未指定this.property。您只需将property的值设置为其自身即可。