此文档源于一个问题,这里直接上问题。
学生 2024年11月7日 19:26
老师同学们大家晚上好,想问一下这个报错是为什么?为什么不可以重复定义?还直接就是编译报错。
老师 2024年11月7日 19:33
我给你举个例子
public void test1() {
int a = 1;
if(true) {
int a = 2;
System.out.println(a);
}
}
这个是会报错的,提示已经被定义过了。这是因为编译器无法区分需要打印的这个 a 是外面的,还是里面的。
老师 2024年11月7日 19:34
这个能理解吗
老师 2024年11月7日 19:38
还有一个经典的例子
这是可以的。为什么呢,因为编译器是可以区分的,因为我们如果在存在成员变量 a 和 局部变量 a 的情况下,认为 this.a 才是得到 S 的成员变量。,那么 System.out.println(a); 这里的 a 是局部变量的 a,而不是成员变量的 a,必须通过 this.a 才能得到成员变量的 a。
老师 2024年11月7日 19:39
所以,我前一个例子中,编译器没办法区分是里面还是外面的,但是我后一个例子,编译器是可以通过有没有 this 来区分是使用成员变量还是局部变量
老师 2024年11月7日 19:42
准确来说,除了 this 外,如果全局变量是静态的,那就通过 有没有 “类名.”来区分是使用成员变量还是局部变量。
老师 2024年11月7日 19:43
for 和这个例子是相似的,需要注意 for 的 () 中定义的变量是局部的,相当于
老师 2024年11月7日 19:45
另外,还有一个例子
这个是可以编译通过的。为什么呢,因为前一个 a 是局部的,只在上面代码块里生效,当跳出了 if 代码块 时,此时在 test1 函数的作用范围内,是不存在 a 的。因此再次定义 int a 是没有问题的。
学生 2024年11月7日 19:51
@老师 所以主要是逻辑上出现的明显问题被编译器解析出来了,而不是由于JVM。例子我理解了。
老师 2024年11月7日 19:53
@学生 是的,编译器进行编译没通过