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

Java构造函数工作原理是什么?子类继承成员变量访问结果为何不符预期?

咱们来逐个解决你的问题~

问题1:Java构造函数的工作原理是什么?

构造函数本质就是Java专门用来初始化对象的特殊方法,核心工作流程可以拆解成这几点:

  • 命名规则严格:必须和类名完全一致,而且没有返回值(连void都不能写,这点和普通方法区别很大)。
  • 自动触发:当你用new关键字创建对象时,JVM会自动匹配调用对应的构造函数——如果你的类里没写任何构造函数,编译器会偷偷给你生成一个无参默认构造函数,它会把实例变量初始化成默认值(比如int类型是0,对象类型是null);但如果你自己写了自定义构造函数,默认的那个就不会生成了,要是需要无参构造得手动加。
  • 父子类的构造顺序:子类构造函数执行时,会优先调用父类的构造函数——默认是父类的无参构造,要是想调用父类带参数的构造,得用super(参数)显式写在子类构造函数的第一行。这是为了保证父类的成员先被初始化,子类才能安全地继承和使用这些成员。
  • 完整执行顺序:从静态到实例,从父到子——先初始化父类的静态变量/静态代码块,再子类的静态变量/静态代码块;然后是父类的实例变量/实例代码块、父类构造函数;最后才是子类的实例变量/实例代码块、子类构造函数。

问题2:为什么代码运行结果是50而非预期的20?

先把你的代码贴出来方便分析:

class A{ int b = 50; } 
class B extends A{ int b = 20; } 
public class Maini{ 
    public static void main(String[] args){ 
        A a = new B(); 
        System.out.println(a.b); 
    } 
}

这个结果的核心原因是Java的成员变量不支持多态,是编译期绑定的,这里出现了「成员变量隐藏」的情况:

  • 变量a的声明类型是A,虽然它实际指向的是B类的对象,但编译器在编译阶段只会根据变量的声明类型来确定要访问哪个b——也就是A类里定义的int b = 50。
  • 对比一下方法的多态:如果是方法的话,会在运行时根据实际对象的类型来调用对应的实现,但成员变量没有这个特性,子类的同名变量只是把父类的变量“隐藏”了,而不是覆盖。

如果想访问B类里的b,你可以把a强制转换为B类型:

System.out.println(((B)a).b); // 这时候输出就是20了

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 07:55:12