You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java中同名静态变量行为及类型转换后变量取值疑问

为什么Java中同名静态变量会出现不同值?

核心原因:静态变量的「隐藏」而非「继承」

Java里静态变量属于类本身,不会被子类继承。如果子类声明了和父类同名的静态变量,这属于「隐藏(hide)」父类的静态变量——两个变量是完全独立的,分别属于父类和子类各自的类空间,不存在指向同一变量的情况。

结合你的代码逐步分析

先明确各静态变量的归属:

  • A.s:属于A类的静态变量
  • C.s:C类自己声明的静态变量,和A.s完全独立,隐藏了父类A的s
  • B类没有自己的s,所以B中访问的s都是A.s
  • D类没有自己的s,所以D中访问的s都是C.s

接下来看代码执行过程中静态变量的变化:

  1. 创建B b = new B(7)

    • 调用父类A的构造器:A(7)将A.s设为7+1=8,同时输出A constructor called! String s is:8
    • B的构造器把自己的实例变量o设为7,b.toString()输出B2S: 7 8(这里的s是A.s)
  2. 创建C c = new C(5)

    • 先调用A的构造器:A(5)将A.s更新为5+1=6,输出A constructor called! String s is:6
    • 再执行C的构造器:把C.s设为5-1=4,输出C constructor called! String s is:4
    • c.toString()输出C2S: 5 4(这里的s是C.s)
  3. 创建D d = new D(3)

    • 先调用A的构造器:A(3)将A.s更新为3+1=4,输出A constructor called! String s is:4
    • 再执行C的构造器:把C.s设为3-1=2,输出C constructor called! String s is:2
    • D的构造器把自己的实例变量o设为3,d.toString()输出D2S: 3 2(这里的s是C.s)

解答你的具体疑问

  • 为什么((A)b).s输出4?
    静态变量的访问是由编译时的类型决定的,和运行时实例类型无关。((A)b)的编译类型是A,所以访问的是A.s——此时A.s在创建D的过程中被更新成了4,所以输出4,而不是你以为的2(2是C.s的值,和A.s完全无关)。

  • 为什么同名静态变量不是同一个?
    子类C声明static int s时,并没有覆盖父类A的s,而是在自己的类空间里创建了一个全新的静态变量。这和实例方法的重写(override)完全不同:静态成员属于类,实例成员属于对象,静态成员不存在动态绑定的逻辑。

额外验证:代码中其他s的输出

  • b.s:编译类型是B,B没有自己的s,所以访问A.s,输出4
  • c.s:编译类型是C,访问C.s,输出2
  • d.s:编译类型是D,继承C的s,访问C.s,输出2

内容的提问来源于stack exchange,提问作者Amadeus

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 14:12:44