Java具有(显然)自相矛盾的作用域

时间:2018-12-05 13:39:36

标签: java scope

对于此代码示例,Java编译器不满意:

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

编译器说:

  

错误:方法main(String [])中已经定义了变量x

但是,Java编译器对此完全满意:

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

这在Java中有点疯狂。当我查找Java范围规则时,几乎总是看到作者描述变量在其所在的块级范围内,除了对象级变量的实例在实例生存期内保留其值。

它们都没有以解释Java编译器处理此处代码示例的方式来解释规则。但是,从这两个明显的例子中我们可以看出,作用域规则并没有真正按照每个人的描述来工作。

请有人正确解释这一点,以便我正确理解吗?

4 个答案:

答案 0 :(得分:2)

int x = 99;
{
  int x = 10;   // variable x defined before is still available, so you can not define it again
  System.out.println(x);
}
System.out.println(x);

并且:

{
  int x = 10;
  System.out.println(x);
}
int x = 99;    // variable x defined before is not available, so you can define it again
System.out.println(x);

答案 1 :(得分:1)

我可以尝试解释,但不了解确切的规则。

在第一个示例中,两个$(document).on("click", ".remove_field", function(e) { //user click on remove text e.preventDefault(); $(this).parent().remove(); x--; }) 在内部作用域中都是已知的。那是不允许的。

在第二个示例中,在内部作用域中,尚未定义外部x。因此没有问题。

答案 2 :(得分:1)

public class Test1 {
  public static void main(String args[]) {
    int x = 99;
    {
      int x = 10; // not allowed because the fist x is visible/known here
      System.out.println(x);
    }
    System.out.println(x);
  }
}

第一个代码中第一个x的范围在main方法中 因此x在方法中的任何地方都是可见的,这就是为什么它不允许 重新声明。

与第二个代码一样,第一个x的范围在块{}内 因此,由于该块之外的x不可见或未知,因此允许声明第二个x

public class Test1 {
  public static void main(String args[]) {
    {
      int x = 10;
      System.out.println(x);
    // x gets out of scope after this closing block
    }
    int x = 99;  // allowed because the first x got out of scope
    System.out.println(x);
  }
}

答案 3 :(得分:0)

这不是Java的问题。当声明并使用第二个x时,作用域变量x已超出范围。