在Java中,我们不能在具有相同名称的另一个变量的同一范围内声明变量:
int someInteger = 3;
...
int someInteger = 13;
语法错误,不编译。但是,如果我们把它放在一个循环中:
for (int i = 0; i < 10; i++) {
int someInteger = 3;
}
不会产生错误,效果很好。我们基本上声明了相同的变量。是什么原因?在这背后我不了解/理解的逻辑是什么?
答案 0 :(得分:9)
想一想,在每次循环之后,范围被“破坏”,变量就消失了。在下一个循环中,将创建一个新范围,并且可以在该范围内再次声明该变量。
出于类似的原因,你也可以这样做
{
int someInteger = 3;
}
{
int someInteger = 13;
}
顺便说一句,Java不允许局部变量阴影,这可能不方便
int x = 3;
{
int x = 13; // error!
}
Consumer<Integer> consumer = (x)->print(x); // ERROR!
// lambda parameter is treated like local variable
Runnable r = ()->{ int x; ... } // ERROR
// lambda body is treated like local block
答案 1 :(得分:4)
Java具有所谓的“块范围”,这意味着任何代码块(由封闭的花括号定义)声明一个变量,那个(并且只有那里)就是它存在的地方。这也意味着每个变量只能在任何给定的块中声明一次。
当你说
时for (int i = 0; i < 10; i++) {
int someInteger = 3;
}
每次迭代都会创建一个新块。它类似于说
{
int someInteger = 3;
}
{
int someInteger = 3;
}
...
在这种情况下,每个块中只有一个名为someInteger
的变量。
当你说
时{
int someInteger = 3;
...
int someInteger = 3;
}
编译器正确地抱怨您在相同的代码块(或范围)中声明了多个具有相同名称的变量。
答案 2 :(得分:2)
在一个块的范围内,会创建一个新的someInteger
,并且阴影是任何其他someInteger
的词法范围。 Variable shadowing上的维基百科条目(部分)
当在特定范围内声明的变量(决策块,方法或内部类)与在外部范围内声明的变量具有相同的名称时,会发生变量阴影。在标识符(名称而不是变量)级别,这称为name masking。
答案 3 :(得分:2)
每个变量都有一个范围。范围嵌套在括号{}
中。当你离开这个范围时,这个上下文消失了,所以你可以定义其他具有相同名称的变量。否则,你不能。
我将举两个例子:
// define new scope named "methodA"
public void methodA() {
int a = 3;
// define new scope named "loop"
for (int i = 0; i < 10; i++) {
int a = 6; // ERROR
}
}
在上述情况下,您将遇到错误。因为&#34;循环&#34;范围在&#34;方法A&#34;范围,所以当你去&#34;循环&#34;时,a的第一个定义仍然存在。范围。
第二种情况:
// define new scope named "methodA"
public void methodA() {
// define new scope inside methodA scope
{
int a = 3;
}
// define new scope named "loop"
for (int i = 0; i < 10; i++) {
int a = 6; // NO ERROR
}
}
上面的代码将成功编译,因为a的第一个定义在a的第二个定义的不同范围内,并且这些范围没有嵌套。
答案 4 :(得分:0)
如果某个类或方法与第一次使用的范围不同,则可以在类或方法中重复使用相同的变量名。
在第一个示例中,两个变量具有相同的范围,因此名称冲突,编译器报告错误。在你的第二个例子中,它们有不同的范围 - 一个在方法中,另一个在for循环中 - 因此没有冲突并且代码编译。
答案 5 :(得分:-1)
不同的范围;
int variables = 3;
....
int variables = 13;
范围一致,肯定编译错误; 但
for (;;;) {
int variables = 13;
}
每个周期等同于重新建立变量变量变量,然后随着范围的变化而消失; JVM堆栈框架就是这样一种机制(局部变量具有分配过程的开始,随着过程的结束而消除);
答案 6 :(得分:-1)
您可以将变量推送到数组中。
Stack myarr = new Stack();
for (int i = 0; i < 10; i++) {
int someInteger = 3;
myarr.push(someInteger);
}
或创建一个变量everyloop
for (int i = 0; i < 10; i++) {
int someInteger+i = 3;
}