java中父类静态变量被所有子类共享,因其属于类而非对象,jvm中仅存一份副本,存于方法区,由父类“拥有”,子类通过类名访问实为同一内存地址,非继承而是可访问性延伸。

Java 中父类的静态变量天然被所有子类实例共享,根本原因在于:静态变量属于类本身,不是某个对象,也不随继承关系复制——它只有一份,存于方法区,由定义它的那个类“拥有”,但所有子类都能直接访问。
静态变量不复制,只有一份内存
父类声明的 static 变量在类加载时初始化一次,整个 JVM 中仅存在一个副本。无论创建多少个父类或子类对象,也无论有多少个子类(ChildA、ChildB、ChildC…),它们读写的都是同一个变量。
- 修改发生在任意子类实例中(如
c1.STATIC_VAR = "new"),其他子类实例、父类实例、甚至通过Parent.STATIC_VAR访问,看到的都是新值 - 这不是“继承来的副本”,而是“同一块内存被多个类名访问”
- 即使子类没写任何代码,也能通过
Child1.STATIC_VAR或new Child2().STATIC_VAR读写它
子类不能真正“拥有”父类静态变量
子类能访问父类 static 成员,但该变量逻辑上仍归属父类。JVM 不会为每个子类分配独立拷贝。
Java JDK 25 来自 OpenJDK 官方归档,版本为 JDK 25,本条下载地址已指向官方 Windows x64 zip 安装包直链,适合调试旧项目或兼容旧版 Java 运行环境。
- 用
Child1.STATIC_VAR赋值,本质仍是修改Parent.STATIC_VAR - 如果子类声明同名 static 变量(如
static String STATIC_VAR = "child";),这叫“隐藏”——不是覆盖,而是新建一个变量,与父类的无关 - 此时
Parent.STATIC_VAR和Child1.STATIC_VAR是两个不同变量,各自独立
实际共享效果演示
假设父类 Parent 定义 public static int count = 0;:
-
new ChildA().count++→count变成 1 -
new ChildB().count++→count变成 2 -
Parent.count、ChildA.count、ChildB.count全部返回 2 - 哪怕没有任何 Parent 实例,只要有一个子类实例改过它,所有地方都同步更新
注意区分“可访问”和“被继承”
严格来说,静态变量不是被子类“继承”的,而是被子类“可见”和“可访问”。Java 规范称其为“类成员的可访问性延伸”,不是面向对象意义上的继承(不参与多态,不可重写)。
- 子类无法用
@Override修饰 static 变量——编译报错 - 静态方法同理:子类里写同名 static 方法,只是隐藏,不是重写
- 真正体现“共享”的,是运行时行为;而“继承”这个词容易让人误以为子类有了自己的副本
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










