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

Java父类引用指向子类对象时访问实例变量为何输出10而非20

问题解答

核心结论

你的理解存在偏差,这是Java的成员变量不支持多态重写的典型表现:Java的多态特性仅对成员方法生效,成员变量只会根据引用的声明类型静态绑定取值,不会根据实际创建的实例类型动态匹配。

执行逻辑梳理

你提供的测试代码如下:

class A
{
    int i = 10;
}

class B extends A
{
    int i = 20;
}

public class MainClass
{    
    public static void main(String[] args)
    {
        A a = new B();
        System.out.println(a.i); //Output of this line
    }
}

逐段拆解运行逻辑:

  • 类加载阶段:JVM会分别加载A、B、MainClass三个类。B类中定义的i并不是重写父类A的i,只是和父类属性同名的、属于B类本身的独立属性,最终创建的B类实例中,会同时存在两个i属性:一个继承自父类A值为10,一个属于子类B值为20。
  • 执行A a = new B();时:会在堆内存中创建B类的实例,同时在栈中创建声明类型为A的引用a指向这个B实例。
  • 执行System.out.println(a.i);时:JVM判断引用a的声明类型是A,直接绑定A类定义的i属性取值,因此输出结果为10。

扩展说明

如果要获取B类定义的i属性值,只需要将引用强转为B类型即可,修改代码如下:

System.out.println(((B)a).i);

上述代码运行后会输出20,因为此时引用的声明类型被转为B,会绑定B类定义的i属性取值。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.07 14:57:02