当前位置: 首页 > 面试题库 >

块范围变量

薄兴昌
2023-03-14
问题内容

这将编译

class X
{  
    public static void main(String args[])
    {
        {
            int a = 2;
        }
        {
            int a = 3;
        }       
    }
}

这不会

class X
{  
    public static void main(String args[])
    {

        int a = 2;

        {
            int a = 3;
        }       
    }
}

我希望两者都能编译(也许这是C的工作方式?)。是什么原因导致无法在外部块中以相同的名称声明一个块中的变量?


问题答案:

简短的答案是:因为这是JLS§6.4中定义Java语言的方式。

您可能从其他语言中使用过,因此允许使用所谓的可变阴影。但是,Java语言的发明者认为这是一个笨拙的功能,他们不希望使用其语言:

此限制有助于检测其他一些非常模糊的错误。

但是,正如作者在JLS的同一部分中指出的那样,您会在Java的其他地方发现阴影:

对于局部变量对成员的重影进行类似的限制被认为是不切实际的,因为在超类中添加成员可能会导致子类不得不重命名局部变量。相关考虑因素也限制了嵌套类成员对局部变量的重影,或者嵌套类内声明的局部变量对局部变量的重影也没有吸引力。

实际上,这意味着以下代码是合法的:

class A {
   int x = 0;
   void m() {
     int x = 10; // Shadows this.x
   }
}

正如作者所描述的,允许通过声明具有相同名称的方法局部变量来对实例变量进行阴影处理,因为有可能某人扩展了A一天的功能,B如果阴影处理是非法的,则您将无法再编译类:

class B extends A {
   void m() {
     int x = 10; // Shadows A.this.x if A declares x
   }
}

如果考虑使用允许遮蔽的C之类的语言,则可以找到如下所示的尴尬代码:

int x;
int main() 
{
  {
    int x = 0;
    {
      extern int x;
      x = 1;
    }
    printf("%d\n", x); // prints 0
  }
  printf("%d\n", x); // prints 1
  return 0;
}

由于可变阴影,该程序不太容易遵循,因此可能无法产生预期的结果。



 类似资料:
  • 本章介绍当模板在访问变量时发生了什么事情,还有变量是如何存储的。 当调用 Template.process 方法时,它会在方法内部创建一个 Environment 对象,在 process 返回之前一直使用。 该对象存储模板执行时的运行状态信息。除了这些,它还存储由模板中指令,如 assign, macro, local 或 global 创建的变量。 它不会尝试修改传递给 process 的数据

  • 问题内容: 我知道变量作用域由块的开始和块的结尾包围。如果在块内声明了相同的变量,则会发生编译错误。但是,请看以下示例。 在这里,可以在方法中重新声明,尽管它已经在类中声明了。但是在块中,无法重新声明。 为什么类范围变量的重新声明不产生错误,而方法范围变量的重新声明却产生错误? 问题答案: 这是因为不是变量,而是实例字段。允许局部变量与字段具有相同的名称。为了区分变量和具有相同名称的字段,我们在实

  • 问题内容: 我知道变量作用域由块的开始和块的结尾包围。如果在块内声明了相同的变量,则会发生编译错误。但是,请看以下示例。 在这里,可以在方法中重新声明,尽管它已经在类中声明了。但是在块中,无法重新声明。 为什么类范围变量的重新声明不产生错误,而方法范围变量的重新声明却产生错误? 问题答案: 这是因为不是变量,而是实例字段。允许局部变量与字段具有相同的名称。为了区分变量和具有相同名称的字段,我们在实

  • 问题内容: 我是PHP新手(仍然),并且继续学习。 我经常必须检索某个变量并访问其属性。 我希望一次检索一次,然后在需要时在同一文件中但在不同块中使用它 但是我怀疑不能在块之间共享,因为它不是全局的。通常的做法是什么? 问题答案: 您在php代码块中放置了太多含义。 这不是全球性的事情。 这些块属于同一PHP脚本。这只是输出HTML的一种简洁方法,仅此而已。您可以用回显HTML代替它,不会有丝毫差

  • 我对Oracle相当陌生,但已经进行了很好的搜索。有人能解释一下与此相关的范围规则吗: 错误: 错误报告-ORA-06550:第17行,第55列:PLS-00201:标识符“VARIABLE2”必须声明ORA-06550:第17行,第17列:PL/SQL:忽略语句06550。00000-“第%s行第%s列:\n%s”*原因:通常是PL/SQL编译错误*行动: 为什么在我第二次尝试输出它时Varia

  • 问题内容: 我想知道使用空块的目的是什么。例如, 有人可以解释 在什么情况下,我们要使用空块。 空块内的所有变量是否仍在继续? 为什么无法访问? 问题答案: 您在帖子中显示的块不是空块,而是静态初始化器。它用于为类的静态变量提供非平凡的初始化 在初始化期间使用的局部变量进入堆栈,但从堆分配的对象除外 您不能访问静态变量,因为您没有声明它。而是在静态初始化程序中声明了局部变量。 如果要创建静态变量,