我刚开始学习Java。我有一些虚假的问题。在这种情况下,我真的不明白为什么:
int j = 5;
for (int j = 0; j < 10; j++) {
// do sth
}
我的编译器说:the variable j is already defined in the scope
。
为什么这第二个j
是个问题?我认为它应该只是影响第一个。
答案 0 :(得分:6)
问题是你要将变量j
声明两次:for
循环中的一个和内部变量。只需删除for
上方的行,就可以了。
局部变量没有被遮蔽 - 也许你记住了字段(但这与你在这里有所不同)。
答案 1 :(得分:4)
更简单但类似的情况是:
int i = 0;
{
int i = 2;
}
所以你有两个i
变量。你引用i
时指的是哪一个?
Java编译器不允许在此处使用“阴影”。这些定义含糊不清,编译器正在努力警告你。
答案 2 :(得分:3)
有关遮蔽和遮挡的规则,请查看Java Language Specification, Section 6.4
他们甚至提供了相同的例子:
由于标识符声明为方法,构造函数或初始化程序块的局部变量,因此不能出现在同名参数或局部变量的范围内,因此以下程序会发生编译时错误:
class Test1 {
public static void main(String[] args) {
int i;
for (int i = 0; i < 10; i++)
System.out.println(i);
}
}
此限制有助于检测一些非常模糊的错误。对局部变量对成员进行阴影的类似限制被认为是不切实际的,因为在超类中添加成员可能导致子类必须重命名局部变量。相关的考虑因素限制了嵌套类成员对局部变量的阴影,或者对嵌套类中声明的局部变量的局部变量的阴影也没有吸引力。
答案 3 :(得分:2)
这样做吧。如果允许您在for循环中声明变量i
,那么您将如何引用在i
循环之前声明的局部变量 for
?您不能使用任何限定名称执行此操作,简单名称将引用for循环变量。这就是不允许的原因。
行为如JLS中所列。来自JLS - Section 6.4:
局部变量(§14.4),形式参数(§8.4.1),异常参数(§14.20)和本地类(§14.3)只能使用简单名称引用 (§6.2),不是合格的名称(§6.6)。
在局部变量,形式参数,异常参数或本地类声明的范围内不允许使用某些声明,因为仅使用简单名称就无法区分声明的实体。< / p>
块中的局部变量声明的范围(第14.4节)是声明出现的块的其余部分,从它自己的初始化器开始,并包括右边的任何其他声明器。局部变量声明语句。
强调我的。
同样,在JLS第6.4节中,指定在同一范围内重新声明局部变量将导致编译时错误:
如果将局部变量v的名称重新声明为v范围内的直接封闭方法,构造函数或初始化程序块的局部变量,则为编译时错误。或者作为v范围内的直接封闭方法,构造函数或初始化程序块的try语句中的catch子句的异常参数;或者作为v的范围内的直接封闭方法,构造函数或初始化程序块的try-with-resources语句中的资源。
答案 4 :(得分:0)
Cause this is a duplicate local variable problem, You already define "j" variable before. Try this:
int i = 5;
for (int j = 0; j < 10; j++) {
// do sth
}
答案 5 :(得分:0)
仅当其中一个变量是方法字段而另一个变量是局部变量时,才会出现阴影。在你的情况下,两者都是局部变量,所以它们不能互相遮挡。
如果两个局部变量共享一个范围的方式与你不能拥有两个同名字段的方式相同,则不能有两个具有相同名称的局部变量。
答案 6 :(得分:0)
int j = 5; // this j is visible to whole method
for (int j = 0; j < 10; j++) {
// so still j is visible to this for loop and you can use it
// but you can't initialize it again
// do sth
}
答案 7 :(得分:0)
您已声明j
变量两次。重写您的代码如下:
for (int j = 0; j < 10; j++) {
// do sth
}
或
int j;
for (j = 0; j < 10; j++) {
// do sth
}