java 中子类不能重写父类的 final 变量。在 java 语言规范中,final 修饰的实例变量表示该字段一旦初始化便不可更改,且 final 关键字不具备多态性,因此无法被“重写”。子类若尝试重新声明同名字段,这属于字段隐藏(field hiding),而非方法意义上的重写;若试图修改该字段的值,则会在编译期直接报错。

子类尝试修改 final 变量会发生什么
当子类继承了一个 final 实例变量后,任何试图通过赋值操作符修改该变量的行为都会导致编译错误。这是因为 final 约束了内存地址上的值不可变性,编译器会拦截此类操作。
public class Parent { protected final int value = 10; } public class Child extends Parent { void test() { this.value = 20; // 编译错误:cannot assign a value to final variable 'value' } }
上述代码展示了典型的编译期错误。由于 value 被标记为 final,它在构造完成后即成为常量状态。即使子类拥有访问权限(如 protected),也无法突破 final 的限制进行二次赋值。这种机制确保了父类定义的不变量在整个继承体系中保持恒定。
子类能否通过同名变量隐藏 final 变量
子类可以通过声明与父类 final 变量同名的新变量来隐藏它,但这不叫重写,而是字段隐藏。隐藏后的变量是独立的,修改子类的变量不会影响父类变量的值。
你是 TypeScript 项目架构专家,专注于脚手架搭建生产就绪的 Node.js 和前端应用。生成包含现代工具链(pnpm、Vite、Next.js)、类型
public class Parent { protected final int value = 10; } public class Child extends Parent { protected int value = 20; // 合法:隐藏父类变量 void show() { System.out.println(value); // 输出 20 System.out.println(((Parent)this).value); // 输出 10 } }
这段代码演示了字段隐藏的实际效果。子类声明了新的 value 变量,覆盖了父类 final 变量的可见性。此时,this.value 引用的是子类的新字段,而强制转换后引用的是父类的原始字段。两者在内存中是两个不同的存储单元,互不影响。这种行为虽然合法,但通常被视为不良实践,因为它破坏了类型系统的直观性。
基于程序中某个输入、条件或结果的具体问题
在上述隐藏示例中,如果子类没有显式声明同名变量,那么无论通过子类实例还是父类引用来访问,看到的都是父类的 final 值。这是由 JVM 的字段解析机制决定的,字段绑定发生在编译期而非运行期。
,
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










