Java 块作用域变量
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/20499554/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Block scope variables
提问by Paolo
This will compile
这将编译
class X
{
public static void main(String args[])
{
{
int a = 2;
}
{
int a = 3;
}
}
}
This won't
这不会
class X
{
public static void main(String args[])
{
int a = 2;
{
int a = 3;
}
}
}
I expected both to compile (maybe it is the way C works?). What is the reason because it is not possible to declare a variable in a block with the same name of one in the outer block?
我希望两者都能编译(也许这是 C 的工作方式?)。无法在块中声明与外部块中同名的变量的原因是什么?
采纳答案by Rafael Winterhalter
The short answer is: Because this is the way the Java language is defined in JLS §6.4.
简短的回答是:因为这是JLS §6.4 中定义 Java 语言的方式。
You might be used from other languages that this so called variable shadowingis allowed. However, the inventors of the Java languages thought this was an awkward feature that they did not want in their language:
您可能会从其他语言中使用这种所谓的变量阴影。然而,Java 语言的发明者认为这是他们不希望在他们的语言中出现的尴尬特性:
This restriction helps to detect some otherwise very obscure bugs.
此限制有助于检测一些非常模糊的错误。
However, you find shadowing elsewhere in Java as the authors state in the same section of the JLS:
但是,正如作者在 JLS 的同一部分中所述,您会在 Java 的其他地方发现阴影:
A similar restriction on shadowing of members by local variables was judged impractical, because the addition of a member in a superclass could cause subclasses to have to rename local variables. Related considerations make restrictions on shadowing of local variables by members of nested classes, or on shadowing of local variables by local variables declared within nested classes unattractive as well.
对局部变量遮蔽成员的类似限制被认为是不切实际的,因为在超类中添加成员可能会导致子类必须重命名局部变量。相关的考虑使得对嵌套类成员对局部变量的遮蔽或对嵌套类中声明的局部变量对局部变量的遮蔽的限制也没有吸引力。
This means in practice that the following code is legal:
这意味着实际上以下代码是合法的:
class A {
int x = 0;
void m() {
int x = 10; // Shadows this.x
}
}
As the authors describe, it is allowed to shadow an instance variable by declaring a method local variable with the same name because of the possibility of someone extending the functionality of A
at one day where you could not longer compile a class B
if shadowing was illegal:
正如作者所描述的那样,允许通过声明一个具有相同名称的方法局部变量来隐藏实例变量,因为有人A
可能会在某一天扩展功能,B
如果隐藏是非法的,您将无法再编译类:
class B extends A {
void m() {
int x = 10; // Shadows A.this.x if A declares x
}
}
If you consider a language like C, where shadowing is allowed, you can find awkward code like this:
如果你考虑像 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;
}
This program is not so easy to follow and might therefore not produce the results you expect, thanks to variable shadowing.
由于可变阴影,该程序不太容易遵循,因此可能不会产生您期望的结果。
回答by Maroun
Because in the second case a
is known inside the static block, so you're trying to redeclareit. The compiler doesn't allow you to do so:
因为在第二种情况下a
在静态块内是已知的,所以您试图重新声明它。编译器不允许你这样做:
public static void main(String args[]) {
{
int a = 2; //a is known only here
} //a will be freed
{
int a = 3; //you can declare it again here
}
}
回答by Duncan Jones
Java doesn't allow you to have two variables with the same name within scope of one another.
Java 不允许您在彼此的范围内拥有两个同名的变量。
In your second case:
在你的第二种情况下:
int a = 2;
{
// the outer 'a' is still in scope
int a = 3; // so this is a redeclare <-- nooo!
}
However, in your first case, each a
is contained within its own scope, so all is well.
但是,在您的第一种情况下,每个a
都包含在自己的范围内,所以一切都很好。
回答by Christian Kuetbach
public static void main(String args[])
{
int a = 2; // I know a
// I know a
{
// I know a
int a = 3; // There can be only one a!
}
}
In the example above you declared a
in you method main()
. From the declaration till the end of the method, a
is declared. In this case you cannout redeclare a in you codeblock.
在上面的示例中,您a
在方法中声明main()
。从声明到方法结束,都a
被声明了。在这种情况下,您不能在代码块中重新声明 a。
Below, you declare a
in a block. It is only known insside.
下面,你a
在一个块中声明。只有内部知道。
public static void main(String args[])
{
{
int a = 2; // I know a
// I know a
}
// Who is a?
{
int a = 3; // I know a!
}
}
回答by Jigar
In Java all local variables will be stored on Stack. So if u write
在 Java 中,所有局部变量都将存储在堆栈中。所以如果你写
class X
{
public static void main(String args[])
{
int a = 2; // At this point var 'a' is stored on Stack
{
/*
Now as the prev. 'main method is not yet complete so var 'a' is still present on the Stack. So at this point compiler will give error "a is already defined in main(java.lang.String[])"
*/
int a = 3;
}
}
}
Hope this help you out
希望这能帮到你
Thanks
谢谢