Java中子类不能隐藏父类成员变量,只能遮蔽——两者物理并存,访问路径不同;推荐用private+getter/setter替代public/protected字段,避免歧义。

Java 中子类不能“隐藏”父类成员变量,只能遮蔽(Shadowing)——这是编译器允许但极易引发误解的行为。真正需要解决的不是“怎么隐藏”,而是如何避免因变量遮蔽导致的逻辑错误和维护难题。
明确:变量遮蔽 ≠ 方法重写
父类字段被子类同名字段“遮蔽”时,两者物理上同时存在,只是访问路径不同:
- 通过父类引用访问 → 看到父类字段值
- 通过子类引用访问 → 看到子类字段值
- 子类中直接用 this.field → 访问子类字段
- 子类中用 super.field → 显式访问父类字段
这容易造成看似“覆盖”实则“并存”的错觉,比如:
class Parent { int x = 10; }class Child extends Parent { int x = 20; }
Parent p = new Child(); System.out.println(p.x); // 输出 10(不是20!)
推荐做法:用 private + getter/setter 替代 public/protected 字段
把父类字段设为 private,提供受控的访问方式:
立即学习“Java免费学习笔记(深入)”;
- 父类字段不暴露,子类无法同名声明遮蔽
- 子类如需扩展行为,可重写 getter 方法(体现多态)
- 语义清晰:字段归属明确,修改安全
private int x = 10;
public int getX() { return x; }
}
class Child extends Parent {
@Override public int getX() { return 20; } // 正确扩展}
若必须共享状态,用 protected 字段 + 明确命名约定
极少数场景(如框架内部、性能敏感代码)需继承字段,应主动规避歧义:
- 父类字段加前缀,如 parentX;子类用 childX
- 或统一在基类定义,子类只读取/修改,不重新声明
- 配合 Javadoc 注明字段用途与生命周期
工具辅助:启用编译器警告与静态检查
让问题在编码阶段暴露:
- IDEA 或 Eclipse 可开启 “Field hiding another field” 警告
- 使用 Checkstyle 规则 VariableDeclarationUsageDistance 或自定义规则拦截同名字段
- CI 中集成 SpotBugs,检测 SHOULD_DELEGATE 类警告
不复杂但容易忽略


















