企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# 变量遮盖 > 原文: [https://javabeginnerstutorial.com/core-java-tutorial/variable-shadowing/](https://javabeginnerstutorial.com/core-java-tutorial/variable-shadowing/) 今天,我们将探讨 Java 的一项罕见功能:**变量遮盖** 首先,让我们定义什么是遮盖字段或方法: 当**被遮盖**时,该字段被视为 * 其声明类的子类声明一个具有**同名**的字段 * 在本地范围内声明具有相同名称和类型的变量 * 用相同名称和类型声明方法参数/参数 ## 局部变量遮盖 ```java public class MyClass { private int count = 10; private void localVariable() { int count = 5; System.out.println("count = "+ count); } public static void main(String[] args) { MyClass test = new MyClass(); test.localVariable(); } } ``` 上面的代码将输出 > `count=5` 因为在**第 7 行**中声明的`count`**局部变量**遮盖了在类级别声明的变量*计数*。 如果要访问实例变量,则需要添加`this`关键字。 ```java private void localVariable() { int count = 5; System.out.println("count = "+ this.count); } ``` ## 方法参数遮盖 即使我们对此不太关注,这种情况也很常见。 下面是一个简单的获取器定义 ```java private int count; public void setCount(int count) { this.count = count; } ``` `this`关键字是解决歧义所必需的。 如果没有`this`,编译器将无法知道我们是否要为其自身分配*计数*方法参数值。 如果删除`this`关键字,则仍然会收到编译警告。 ## 超类字段遮盖 让我们考虑以下类: ```java public class SuperClass { protected String val = "SUPER_VAL"; protected void display() { System.out.println("val = "+this.val); } } public class ChildClass extends SuperClass { private String val; public ChildClass(String value) { this.val = value; } public static void main(String[] args) { ChildClass child = new ChildClass("CHILD_VAL"); child.display(); } } ``` 执行给出: > `value = SUPER_VAL` 在`SuperClass`中声明了`val`字段,但在`ChildClass`中被遮盖了,因为后者声明了另一个具有相同**名称和类型**的字段。 尽管已使用`CHILD_VAL`实例化了`ChildClass`,但执行`child.display()`却给您`SUPER_VAL`。 原因很简单。 创建子实例时,有 2 个变量`val`。 通过构造器,来自`SuperClass`的一个具有值`SUPER_VAL`,来自`ChildClass`的一个具有注入值`CHILD_VAL`。 调用`display()`方法时,由于它是在**超类**中定义的,因此它是超类的**上下文**中的`val`字段。输出显示`SUPER_VAL`也就不足为奇了。 ```java public class ChildClass extends SuperClass { private String val; public ChildClass(String value) { this.val = value; super.val = value; } public static void main(String[] args) { ChildClass child = new ChildClass("CHILD_VAL"); child.display(); } } ``` 在上面修改的代码中,我们将`SuperClass`中隐藏的`val`字段的值强制为`super.val = value`,输出给出: > `value = CHILD_VAL` 现在让我们在层次结构中添加另一个类 ```java public class AncestorClass { protected String val = "ANCESTOR_VAL"; } public class SuperClass extends AncestorClass { protected String val = "SUPER_VAL"; } public class ChildClass extends SuperClass { private String val = "CHILD_VAL"; public void displayVal() { System.out.println("val = " + super.val); } public static void main(String[] args) { ChildClass child = new ChildClass(); child.displayVal(); } } ``` 显然,输出将显示 > `val = SUPER_VAL` 现在的问题是:如果要显示祖先类的`val`值,该怎么办? 显然,仅`super`关键字引用了类层次结构中的第一个父类。 救援人员来了。 实际上,我们可以将代表当前类实例的**关键字强制**应用于类层次结构中的特定类型! ```java public class ChildClass extends SuperClass { private String val = "CHILD_VAL"; public void displayVal() { System.out.println("val = " + ((AncestorClass) this).val); } public static void main(String[] args) { ChildClass child = new ChildClass(); child.displayVal(); } } ``` 这次,我们确实有 > val = ANCESTOR_VAL