69. Java 嵌套类 - 变量遮蔽现象
阴影(Shadowing)现象
在 Java 中,“阴影”或“遮蔽”现象指的是当在嵌套作用域中使用相同名称的变量时,内层作用域中声明的变量会隐藏外层作用域中同名的变量。这意味着在内层作用域中直接使用该名称时,总是引用离当前作用域最近的变量。如果需要访问被内层变量遮蔽的外层变量,则必须使用限定名称。
1. 何为“阴影”?
-
示例说明: 假设在外部类中声明了变量
x,而在内部类或方法参数中又声明了同名变量x,此时内层的x会覆盖外层的x。例如:public class ShadowTest { public int x = 0; // 外层变量 class FirstLevel { public int x = 1; // 内层变量 void methodInFirstLevel(int x) { // 方法参数,也命名为 x System.out.println("x = " + x); // 输出方法参数 x System.out.println("this.x = " + this.x); // 输出 FirstLevel 的 x System.out.println("ShadowTest.this.x = " + ShadowTest.this.x); // 输出外部类的 x } } public static void main(String... args) { ShadowTest st = new ShadowTest(); ShadowTest.FirstLevel fl = st.new FirstLevel(); fl.methodInFirstLevel(23); } } -
运行输出:
x = 23 this.x = 1 ShadowTest.this.x = 0x = 23:方法参数x遮蔽了其他同名变量;this.x = 1:this.x指向当前FirstLevel内部类的成员;ShadowTest.this.x = 0:通过限定名称访问外部类ShadowTest的x字段。
2. 如何访问被隐藏的变量
在出现变量遮蔽时,可通过以下方式访问各层次的变量:
- 直接使用变量名
- 在当前作用域内,如果有同名变量,则直接引用该变量。例如在
methodInFirstLevel中直接写x就指向方法参数。
- 在当前作用域内,如果有同名变量,则直接引用该变量。例如在
- 使用
this.x- 在内部类中,
this.x指向当前对象的字段。如果内部类有自己的字段x,则this.x访问的是内部类的x。
- 在内部类中,
- 使用
OuterClassName.this.x- 在内部类中,如果需要访问外部类的同名变量,可以使用限定名称,例如
ShadowTest.this.x来明确指定外部类的x。
- 在内部类中,如果需要访问外部类的同名变量,可以使用限定名称,例如
3. 为什么会出现阴影现象
- 作用域规则:
Java编译器在遇到同名变量时,会优先查找当前作用域内的变量。这种“就近原则”会导致内层声明的变量自动遮蔽外层的变量。 - 设计初衷: 允许在不同作用域中使用同一名称,可以在局部上下文中突出参数与局部变量的含义,但同时要求开发者在需要访问外层变量时使用限定名称以消除歧义。
4. 小结
- 阴影/遮蔽: 当内层作用域中声明的变量与外层同名时,内层变量将遮蔽外层变量,使得直接引用只得到内层变量。
- 访问外层变量:
使用
this.x可访问内部类自身的字段,使用OuterClass.this.x则能访问外层类的变量。 - 命名注意: 为了提高代码可读性,通常应避免出现过多同名变量,但在必要时,通过限定名称来消除歧义是 Java 的标准做法。