Java 构造方法的继承/构造方法的调用顺序(二)

Java 继承中的构造方法调用规则详解 最近在学习 Java 继承时,对构造方法的调用规则产生了一些疑问:如果父类没有无参构造会怎样?多级继承时要怎么处理?子类自身构造方法又会如何影响调用链?通过一番研究和实验,我整理了这篇笔记,分享给大家,希望能帮助到有同样困惑的小伙伴。默认行为:子类构造方法会自动调用父类的无参构造(super()无参构造缺失:如果父类没有无参构造,子类必须用super(参数)手动调用,否则报错。多级继承:构造方法从顶层父类逐级调用到子类,每个类只需关心自己的直接父类。全无参构造。 阅读详情

我们在构造方法的继承、调用顺序(一)一文中,已经了解过子类的构造过程中,构造方法是如何调用的。

那么,我们看下面一个例子来巩固一下:

package com.company;


public class Main {
    public static void main(String[] args) {
        new B(6); //B类型实例化,会调用到B类型的构造函数
    }

    public static class A {
        private int f1 = 7;                 //(1)

        public A(int b) {                   //(A())
            this.f1 = b;			        //(2)
            System.out.println("step1");    //(3)
            initialize();			        //(4)
        }

        protected void initialize() {       //(5)
            System.out.println("step2");
            System.out.println(f1);
        }
    }

    public static class B extends A {   // B是A的子类,所以才能在B的构造方法中调用A的构造方法
        protected int f1 = 3;              //(6)

        public B(int f1) {   //B类型实例化,会调用到B类型的构造方法
            super(f1);       //(7)
            this.f1 += f1;   //(8)
            initialize();    //(9) 
        }

        protected void initialize() {      //(10)
            System.out.println("step3");
            System.out.println(f1);
        }
    }
}

输出:

step1
step3
0
step3
9

在上面的代码中,new B(6) 对子类B进行实例化,
new B(6) ---->super(6) ,但是这个时候并没有对B类的成员B.f1初始化,
这是为什么呢?
这是因为B的父类A还未完成构造,jvm会先对父类A进行构造,包括对A.f1初始化 —> A,构造()两个步骤,
在A的构造方法中,调用了initialize(),这个initialize是 B.initialize(),
这是因为A.initialize在此处被B.initialize()所重写,如果将A.initialize修改为private,那么这个重写将不成功(编译不会报错)。

那么这个调用顺序如下;
new B(6) ——> (7)super(f1)检查到B有父类A,进入父类A的构造过程 ——>
——> (1) A.f1初始化 ——> A.A() ——>{(2)(3)(4)——>(10) --(7)完成}
——> 进入子类B的构造过程 ——>
——>(6) B.f1初始化 ——>(8) (此刻B.f1已被初始化) ——>(9)——>(10)。

A.initialize被重写,会导致调用顺序发生变化,为了验证这个问题,我们将上面A类中的代码修改一下:

public static void initialize() {       //(5)

编译报错:
Error:(33, 24) java: com.company.Main.B中的initialize()无法覆盖com.company.Main.A中的initialize()
被覆盖的方法为static

我们将代码再次修改,验证:
修改A类中的代码回原样:

protected  void initialize() {       //(5)

修改B类中的代码:

private void initialize() {      //(10)

再次验证,发现(4)处调用的是A.initialize(),而不是B.initialize,
这是因为B虽然对A的initialize进行了重写,但是由于B中initialize使用了private限定,导致在A类中无法访问B.initialize,最后jvm仍然调用了A的initialize。

对Java中构造方法调用顺序的理解 ​ 之前对构造函数的调用顺序一直很迷,只知道很死板地记着“父类构造函数先于子类构造函数调用”,但是其中的原因并没有去深究。前几周大概看了一遍JAVA编程思想,真的是博大精深……但是对这个概念起码有了一点自己的看法。欢迎指正哦~ class Fu{ } class Zi extends Fu{ } public class Demo1 { public stati... 阅读详情

相关推荐

Java构造方法继承规则:深度解析父类无参构造的调用机制

本文详细探讨了Java中构造方法继承的基本原理、调用规则、特殊情况处理机制以及最佳实践。构造方法在继承中具有特殊性,子类不会继承父类的构造方法,但必须直接或间接调用父类构造方法,且父类构造方法总是先于子类执行。文章通过代码示例和图表展示了隐式和显式调用父类构造方法的方式,并分析了父类没有无参构造时的处理机制。此外,文章还讨论了构造方法调用链、初始化顺序、设计模式对比以及JVM层面的处理过程。最后,提出了防御性编程实践和继承设计原则,帮助开发者避免常见陷阱,如父类没有无参构造时的编译错误。通过本文,读者可以深

记录学习的过程 830

java继承构造函数调用顺序问题

有两个类,一个Yuan继承Yan,调用Yuan的有参的构造函数,其调用顺序如何,且看代码: package cn.yan.teststarter.test; public class Yan { private String name; static { System.out.println(8); } public Yan() { ...

DayDayUpTianTian的博客 557

java-继承构造方法&构造方法、代码块和静态代码块的执行顺序以及子父类执行顺序

文章目录前言一、构造方法二、使用步骤1.引入库2.读入数据总结 前言 一、构造方法 示例:pandas 是基于NumPy 的一种工具,该工具是为了解决数据分析任务而创建的。 二、使用步骤 1.引入库 代码如下(示例): import numpy as np import pandas as pd import matplotlib.pyplot as plt import seaborn as sns import warnings warnings.filterwarnings('ignore') im

weixin_52509741的博客 1356

继承之间的构造方法调用顺序

java

weixin_46672808的博客 269

点云配准实战:用DGCNN+Transformer+SVD搞定3D模型对齐(附PyTorch代码)

本文详细介绍了基于深度学习的点云配准实战方法,重点解析了Deep Closest Point (DCP)模型。该模型融合了DGCNN、Transformer和可微分SVD三大核心模块,能够端到端地预测点云间的刚性变换,有效克服传统ICP算法对初始位置敏感、易陷入局部最优的缺点。文章提供了完整的PyTorch代码实现、ModelNet40数据集处理、训练策略及显存优化技巧,旨在帮助开发者在机器人、自动驾驶等领域实现精准的3D模型对齐。

weixin_29061041的博客 155

华为ITR流程实战指南:从设计到落地的全流程解析(附完整方案下载)

本文深度解析华为ITR流程从设计到落地的全流程实战指南。ITR不仅是高效处理客户问题的“救火”系统,更是驱动产品改进、预防问题的企业“免疫系统”。文章详细拆解了流程设计的四步走策略、三层技术支持体系的组织保障、以闭环改进为核心的考核激励,并探讨了如何借鉴其精髓,优化自身问题管理,实现从被动响应到主动服务的跨越。

y2z3a4b5c的博客 380

构造方法的调用顺序

构造方法的调用时遵照下面的顺序的: 1、调用基类的构造方法。这个步骤会不断的反复递归下去,首先是构造这种层次结构的根,然后是下一层派生类,等等。直到最低层的派生类。 2、按声明顺序调用成员的初始状态设置模块 3、调用派生类构造方法的主体 构造方法的调用顺序非常重要。 当进行继承时,我们已经知道了基类的一切,并且可以访问基类中任何声明为public和protected的成员。这意味着在派生类中

wuliEcho的博客 1736

国外无人机蜂群作战典型战例及发展趋势

参与袭击的无人机为简易组装的固定翼飞机,采用小排量活塞发动机和手机GPS通信模块零件,机翼为轻木加泡沫板混合结构,尾梁为铝合金方管,主要依靠胶带粘接,以上全部配件均可在商用市场买到,成本较低,可在短时间内装配完成。③战场纵深短、瞬时性强。蜂群作战的参战数量显著增加,这一方面得益于无人机技术的飞速发展使得廉价无人机可以大量生产和仿制,另一方面凭借迅速发展的投放和回收技术以及集群控制技术,使得无人机蜂群可在极短时间内实现编队饱和攻击,在快速消耗敌方高价值防空武器系统的同时,保证己方物资系统的突防概率。

renhongxia1的博客 2481

java程序的执行顺序

一、先执行内部静态对象的构造方法,如果有多个按定义的先后顺序执行;静态对象在构造的时候也是也先执行其内部的静态对象。 二、再调用父类的构造方法(父类还有父类的话,从最开始的基类开始调用),如果没有明显指定调用父类自定义的构造方法,那么编译器会调用默认的父类构造方法super()。但是如果要调用父类自定义的构造方法,要在子类的构造方法中明确指定。 三、按声明顺序将成员引用对象变量初始化。

Faith的博客 863

Python实战:用BM3D算法给老照片去噪(附完整代码+数据集)

本文详细介绍了如何使用Python和BM3D算法为老照片进行高效去噪。通过完整的代码实现和数据集,读者可以快速掌握图像去噪技术,包括环境配置、算法原理、参数调优及效果评估,帮助恢复珍贵老照片的清晰度。

weixin_29057237的博客 239

网络流量监测技术

NetFlow是Cisco公司提出的网络数据包交换技术,该技术首先被用于网络设备对数据交换进行加速,并可同步实现对高速转发的IP数据流(Flow)进行测量和统计。  随着宽带互联网在中国 的迅速发展,全国各大电信运营商的网络规模都在不断扩张,网络结构日渐复杂,网络业务日趋丰富,网络流量高速增长。电信运营商需要通过可靠、有效的网络业 务流量监测系统对其网络以及网络所承载的各类业务进行及时、准

红杉树(ecitnet)的博客 5540

java中构造函数在继承中的调用顺序是什么?

这个过程确保了父类在子类之前被完全初始化,这样子类就可以安全地访问父类的任何非静态成员。这个输出清楚地展示了构造函数在继承中的调用顺序。

蜗牛Clear的博客 480

PPT制作能力在职场中真的重要吗?一定要美术功底才能学好PPT吗?

我推出PPT技能培训专栏啦!好的PPT可以让你事半功倍、2023拥有PPT能力还可以让你具备一门极有价值的斜杠能力。更多内容请进:梦幻训练营专栏。专栏内会用本人积累的近10年的PPT学习方法论在短时间内教会你如何制作出精美绝伦的PPT,每篇教程后还会免费赠送一些小福利,不可多得。

打造全国最全的AI Agent开发知识领域的博客 728

java继承中执行构造方法的顺序

分析:首先一切都是从main里第一条语句开始,new Derived("C"),然后跳到public Derived(String s),因为类牵扯到继承,要先将父类初始化,所以必须要有super,但是我们写了Derived的有参构造方法,所以系统不会给我们写无参的构造方法,同时父类的构造方法public Base(String s)是有参的,有参是不能不写的,所以在public Derived(String s)里面必须得有super(形参),可是我们这里的代码没有super(形参),会编译错误。

2301_80369371的博客 827

C++ int转四字节数组

字节转换

我不是码农的博客~~~ 974

清华源pip install出现ERROR: Could not find a version that satisfies the requirement的解决方案

本文主要介绍了清华源pip install出现ERROR: Could not find a version that satisfies the requirement的解决方案,希望能对学习python的同学们有所帮助。 文章目录 1. 问题描述 2. 解决方案

weixin_43178406的博客 8万+

Java中含有多层继承关系的构造方法的调用顺序

基础不牢,地动山摇。最近在看《Java编程思想》回顾JavaSE中的重点知识。会一直整理下来。接下来就要说一个含有多层继承关系的对象的构造方法调用顺序是什么样的。 父类的构造方法总是在子类的构造方法中被调用,而且按照继承层次逐渐向上链接,来使得每个父类的构造方法都能得到调用。实际是向上链接到最顶层的父类之后开始调用。子类只能访问自己的成员,不能访问父类中的成员(父类中的成员一般都是private类型),只有父类才有合适的权限对自己的元素进行初始化,因此,必须让每个构造方法都能够得到调用,否则的话无法创建完整

EEEEEEcho的博客 1132

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

java在调用子类构造方法之前会先调用父类没有参数的构造方法

在Java中,当调用子类的构造方法时,Java会自动在调用子类构造方法之前调用父类的无参构造方法(如果存在)。如果父类没有无参构造方法,子类构造方法必须显式调用父类的其他构造方法。这个机制背后的原因是为了确保父类部分的初始化在子类部分之前完成,从而保证对象创建过程中各部分状态的一致性和正确性。

Flying_Fish_roe的博客 1871

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

java继承构造方法调用顺序

第一种情况: 运行结果: People(String name) Child(String name) 分析:1.首先根据带参数的对象去找相应类的构造方法,在Child类中找到了带参数的构造方法, 2.因为有super(name)的语句存在,所以会去调用父类的带参数的构造方法,输出People(String name); 3、回到子类中执行输出Child(String name)。 第二种情况: 运行结果: People() Child(String name) 分析: 1、创建了一个带参数的对象,

wuwndj的博客 3681

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

Java-构造方法调用顺序

public class TestSuper02 { public static void main(String[] args) { System.out.println("开始创建一个ChildClass对象......"); new ChildClass(); } } class FatherClass { public FatherClass() { System...

li_xunhuan的博客 1787

继承中的构造方法执行顺序

继承中的构造方法执行顺序 在子父类中,创建子类对象,调用子类的构造方法, 在子类的构造方法的第一行代码如果没有调用父类的构造或者没有调用子类的其他构造,则默认调用父类无参构造。 为什么要调用父类构造? 因为需要给父类的成员变量初始化。肯定会先把父类的构造执行完毕,在去执行子类构造中的其他代码。 super(实参列表);语句 在子类的构造方法中使用,用来调用父类中的构造方...

云飞扬°的博客 2915

一文整懂 Java 中静态代码块 / 初始块 / 构造方法的执行顺序

一文整懂 Java 中静态代码块 / 初始块 / 构造方法的执行顺序 相信,刷过面试题应该都碰到过很多题,关于类继承后 Java 中静态代码块 / 初始块 / 构造方法的执行顺序问题,每每记一下又忘了,那么,今天来用不多的时间复习一下 01.静态代码块 / 初始块 / 构造方法的执行顺序 package erdan.demo; public class Demo { static { System.out.println("静态代码块 111"); } stat

Java Pro 19万+

Java 构造方法的继承/构造方法的调用顺序(一)

在java中,假如一个类Money 存在private 成员amount,另一个类USD继承自这个类,那么 USD子类中与这个amount成员是一个什么样的关系呢? 我们来看一段代码,父类Money : 这里解释一下,抽象类其实也是有构造方法的,只不过抽象类是不能被实例化,也就是说,抽象类的构造方法不能在对抽象类进行实例化的场合调用。 那么言外之意,如果在某个场合抽象类的方法被调用并不会引起抽象类的实例化,那么它就允许被调用。我们将在下面的代码中来介绍这样一种特殊情况。 public abstract cl

roddger1的博客 1275

Java中继承关系的构造函数的调用顺序

情况一:在JAVA中,我们通常把C中的函数叫做方法。对于子类调用父类的构造方法可以做出如下解释: 子类无条件地继承父类的不含参数的构造方法。如果一个类中没有构造函数的话编译器会默认为该类创建一个无参空构造器     如果子类自己没有构造方法,则它将继承父类的无参数构造方法作为自己的构造方法; 下面用一个例子验证下 public class Demo03 { public static

show123time的博客 1932

子类调用父类构造方法 java_JAVA子类调用父类构造方法

父类的构造方法不能被子类继承。以下语句中MyException类继承了java.lang.Exception类。public class MyException extends Exception{} //MyException类只有一个隐含的默认构造方法尽管在Exception类中定义了如下形式的构造方法:public Exception(String msg)但MyException类不会继承...

weixin_34432821的博客 3247

继承中构造方法

1、子类初始化之前,先会进行父类的初始化。 2、子类中所有的构造方法默认都会访问父类中空参数的构造方法。可以通过super(参数)指定父类带参构造。 3、实例化类对象时,如果只有无参构造方法,类的属性会被赋默认值。 4、当子类需要父类的功能,而子类有自己特有内容时,可以重写父类中的方法。继承重写父类方法,即沿袭了父类的功能,又定义了子类特有的内容。 5、继承中分层初始化:1、先进行父类初始化,然后进行子类初始化。2、属性对象、变量的执行优先构造方法。

weixin_40017062的博客 2889
上一篇: Java 基础类型转换、父子类的类型转换
下一篇: JAVA中的Class对象
容sir
博客等级 码龄17年 13粉丝 23原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值