以下方法不起作用,因为内部块声明了与外部块中的变量同名的变量.显然,变量属于声明它们的方法或类,而不属于声明它们的块,因此我无法编写一个简短的临时块来进行调试,将外部作用域中的变量推送到阴影片刻:
void methodName() { int i = 7; for (int j = 0; j < 10; j++) { int i = j * 2; } }
几乎我用过的每一种块范围的语言都支持这种语言,包括我在学校编写解释器和编译器的琐碎小语言.Perl可以做到这一点,就像Scheme一样,甚至是C.甚至PL/SQL都支持这个!
这个Java设计决策的基本原理是什么?
编辑:有人指出,Java确实有块范围.我问的概念的名称是什么?我希望我能从那些语言设计课程中记住更多.:)
严格来说,Java 确实有块范围的变量声明; 所以这是一个错误:
void methodName() { for (int j = 0; j < 10; j++) { int i = j * 2; } System.out.println(i); // error }
因为'i'不存在于for block之外.
问题是Java不允许您创建一个变量,该变量与在同一方法的外部块中声明的另一个变量的名称相同.正如其他人所说,据说这样做是为了防止难以辨认的错误.
因为作者故意这样做并且通过忘记现在有两个具有相同名称的变量而完全搞砸了,这种情况并不少见.它们更改内部变量名称,但保留使用变量的代码,现在无意中使用了以前隐藏的变量.这导致程序仍然编译,但执行缓慢.
同样,不小心隐藏变量并改变程序的行为并不罕见.在不知不觉中遮蔽现有变量可以像在上面提到的那样轻松改变程序.
允许这种阴影并没有太大的好处,他们认为它太危险了.说真的,只需将你的新变量称为别的东西,问题就会消失.
我相信理由是大多数时候,这不是故意的,它是一个编程或逻辑缺陷.
在一个像你一样微不足道的例子中,它显而易见,但是在一大块代码中,意外地重新声明一个变量可能并不明显.
ETA:它也可能与java中的异常处理有关.我认为这个问题的一部分是在一个问题中讨论的,该问题涉及为什么在try/finally范围内没有在try部分中声明的变量.
我猜,它会导致难以发现的错误.它与C#类似.
Pascal不支持这一点,因为你必须在函数体上面声明变量.