Java对象初始化分析
请听题
当我们在主函数中new B()的时候,控制台会输出什么呢?
答案与分析写在下方,最好是自己思考一下~
我们有两个类A、B。各自有一个属性Num,A.Num=10,B.Num=20。
B继承A。
class A{
int Num = 10;
public A(){
run();
}
public void run(){
System.out.println("ANum = "+Num);
}
}
class B extends A{
int Num = 20;
public B(){
run();
}
public void run() {
System.out.println("BNum = "+Num);
}
}
下面是答案:
答案就是:
0
20
接下来我就用简单的方式分析一下这是为什么:
1、当子类被实例化的时候,其实子类的构造方法 B()内,Java会自动调用super()。
Java的对象实例化大家应该都懂吧~
子类在构建前,必须先构建父类,不然子类从何来继承呢~
所以java会在子类构造函数中自动帮你调用父类构造方法。
2、此时Java帮我们自动调用父类构造方法super(),也就是A(),那么A方法调用前,A类是不是要加载进内存呢~
所以,此时A类的Num状态为:
A:
int Num = 0;
大伙都知道,类在加载到内存后,其内的数据会有默认值,比如int默认0,String默认null;
还有个小知识点,我们用代码来表示:
class A{
//int Num = 10; 其实这个创建变量,并赋值的操作是两步(废话了哈)
int Num; 这是第一步,创建了变量Num
第二步就比较诡异啦
public A(){
super();
Num = 10; 赋值是在构造方法内执行的
run();
}
}
那么B类,也就是子类,也是同理。
3、这个时候,A类运行构造方法A(),A调用最上层object的构造方法大家也懂~ 然后看上面代码,是不是该执行下面的了
执行完Num = 10后
A类:
int Num = 10 这个时候A的Num就确定是10了
run();
接下来是run()方法了!
注意!
这个时候的run方法,可能有小伙伴会以为输出ANum = 10;
这里就是个陷阱,主函数中new的是B,那么这里就使用了多态的概念:
子类继承父类,执行其中方法的时候,看的就是调用方法的实例是谁。
new B() ---> B里面的super() ----> A()构造方法
上面这个流程看下来,调用者是B,没错吧。
那么A里面的run()方法,在调用时,会去B里面调用B的run()
此时B类都还没开始实例化呢,只是A进行了初始化
class B{
B才只进行了加载进内存这个操作
int Num = 0;
}
所以第一个输出结果是0!
4、此时A的构造方法执行完了,那就剩下B了呗,B按着顺序执行完,Num赋值为20,然后输出20~
文字表达不一定大伙都懂我的‘高级’文笔,下面我准备一张图:
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构
· 字符编码:从基础到乱码解决
· 提示词工程——AI应用必不可少的技术