详解java中继承关系类加载顺序问题
发布时间 - 2026-01-11 01:46:43 点击率:次详解java中继承关系类加载顺序问题

实例代码:
/**
* Created by fei on 2017/5/31.
*/
public class SonClass extends ParentClass{
public SonClass(){
System.out.println("SonClass's constructor");
}
{ System.out.println("SonClass's block");}
static {
System.out.println("SonClass's static block ");
}
public static void main(String[] args) {
System.out.println("------ main start ------ ");
new SonClass();
System.out.println("------ main end ------ ");
}
}
class ParentClass{
public ParentClass(){
System.out.println("ParentClass's constructor");
}
{ System.out.println("ParentClass's block");}
static {
System.out.println("ParentClass's static block ");
}
}
运行结果:
ParentClass's static block SonClass's static block ------ main start ------ ParentClass's block ParentClass's constructor SonClass's block SonClass's constructor ------ main end ------
根据运行结果,一目了然,在执行 main 方法中 new SonClass() 之前,就在类加载之后执行了类中 static 代码块。然后再进入main方法,执行new操作,当然显而易见,在执行new子类操作的时候,是要先进行其父类的构造,即先执行父类的构造代码块(代码中只用大括号包裹的那段代码)以及构造函数 ,然后再执行子类的构造代码块以及构造函数。
修改一下代码,再来看看运行的结果:
/**
* Created by fei on 2017/5/31.
*/
public class SonClass extends ParentClass{
ParentClass parentClass;
public SonClass(){
System.out.println("1");
}
public SonClass(String name){
System.out.println("2");
this.name = name;
parentClass = new ParentClass("FEI");
}
public static void main(String[] args) {
System.out.println("------ main start ------ ");
new SonClass("fei");
System.out.println("------ main end ------ ");
}
}
class ParentClass{
String name ;
public ParentClass(){
System.out.println("3");
}
public ParentClass(String name){
System.out.println("4");
this.name = name ;
}
}
运行的顺序是:
------ main start ------ 3 2 4 ------ main end ------
第一个规则:子类的构造过程中,必须调用其父类的构造方法。一个类,如果我们不写构造方法,那么编译器会帮我们加上一个默认的构造方法(就是没有参数的构造方法),但是如果你自己写了构造方法,那么编译器就不会给你添加了,所以有时候当你new一个子类对象的时候,肯定调用了子类的构造方法,但是如果在子类构造方法中我们并没有显示的调用基类的构造方法,如:super(); 这样就会调用父类没有参数的构造方法。
第二个规则:如果子类的构造方法中既没有显示的调用基类构造方法,而基类中又没有无参的构造方法,则编译出错,所以,通常我们需要显示的:super(参数列表),来调用父类有参数的构造函数,此时无参的构造函数就不会被调用。
总之,一句话:子类没有显示调用父类构造函数,不管子类构造函数是否带参数都默认调用父类无参的构造函数,若父类没有则编译出错。
还是两个类,我们再更改一下。
/**
* Created by fei on 2017/5/31.
*/
public class SonClass extends ParentClass{
private String name = "SonClass";
public SonClass() {
printName();
}
public void printName() {
System.out.println("SonClass print name: " + name);
}
public static void main(String[] args){
new SonClass();
}
}
class ParentClass{
private String name = "ParentClass";
public ParentClass() {
//System.out.println(this.getClass());
printName();
}
public void printName() {
System.out.println("ParentClass print name: " + name);
}
}
看了上面的两个例子,最后这个例子就很容易被迷惑,可能有人会觉得运行结果是类似这样的:
ParentClass print name: ParentClass SonClass print name: SonClass
或者是:
ParentClass print name: SonClass SonClass print name: SonClass
但真正的结果是这样的:
SonClass print name: null SonClass print name: SonClass
为什么会这样,其实只要打开代码中父类构造器中的这句注释,就很容易理解了:System.out.println(this.getClass())
结果是:
class SonClass
没错,父类中的this引用是子类实例对象,所以在父类构造函数里调用的还是子类的printName()方法。具体原因也并我能十分肯定,我个人浅见,是因为虽然我们调用了父类的构造方法,但是我们并没有实例化出父类的实例对象,所以this还是指向的是子类的引用。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!
# java继承关系类加载顺序问题
# java继承关系类加载顺序实例详解
# java中子类继承父类
# 程序运行顺序的深入分析
# java中 IO 常用IO操作类继承结构分析
# java子类继承父类实例-披萨的选择实现代码
# java用接口、多态、继承、类计算三角形和矩形周长及面积的方法
# Java内部类的继承(全)
# JAVA 继承基本类、抽象类、接口介绍
# java类中元素初始化顺序详解
# Java类初始化和实例化中的2个“雷区”
# 解析Java虚拟机中类的初始化及加载器的父委托机制
# Java类继承关系中的初始化顺序实例详解
# 子类
# 类中
# 很容易
# 然后再
# 其父
# 的是
# 加载
# 就会
# 是因为
# 就在
# 看了
# 结果是
# 第一个
# 是这样
# 就不
# 当你
# 你自己
# 我能
# 用了
# 希望能
相关栏目:
【
网站优化151355 】
【
网络推广146373 】
【
网络技术251813 】
【
AI营销90571 】
相关推荐:
如何快速重置建站主机并恢复默认配置?
PHP 500报错的快速解决方法
javascript基于原型链的继承及call和apply函数用法分析
linux top下的 minerd 木马清除方法
如何快速搭建FTP站点实现文件共享?
大型企业网站制作流程,做网站需要注册公司吗?
深圳网站制作培训,深圳哪些招聘网站比较好?
实现点击下箭头变上箭头来回切换的两种方法【推荐】
Laravel怎么生成二维码图片_Laravel集成Simple-QrCode扩展包与参数设置【实战】
魔毅自助建站系统:模板定制与SEO优化一键生成指南
Laravel如何部署到服务器_线上部署Laravel项目的完整流程与步骤
如何用已有域名快速搭建网站?
为什么php本地部署后css不生效_静态资源加载失败修复技巧【技巧】
Laravel定时任务怎么设置_Laravel Crontab调度器配置
java中使用zxing批量生成二维码立牌
谷歌浏览器下载文件时中断怎么办 Google Chrome下载管理修复
HTML 中动态设置元素 name 属性的正确语法详解
学生网站制作软件,一个12岁的学生写小说,应该去什么样的网站?
UC浏览器如何设置启动页 UC浏览器启动页设置方法
Laravel怎么配置S3云存储驱动_Laravel集成阿里云OSS或AWS S3存储桶【教程】
香港服务器建站指南:免备案优势与SEO优化技巧全解析
Laravel项目如何进行性能优化_Laravel应用性能分析与优化技巧大全
Laravel Pest测试框架怎么用_从PHPUnit转向Pest的Laravel测试教程
Laravel如何使用withoutEvents方法临时禁用模型事件
如何在IIS7上新建站点并设置安全权限?
Win10如何卸载预装Edge扩展_Win10卸载Edge扩展教程【方法】
Laravel观察者模式如何使用_Laravel Model Observer配置
焦点电影公司作品,电影焦点结局是什么?
如何在企业微信快速生成手机电脑官网?
如何在Windows环境下新建FTP站点并设置权限?
宙斯浏览器视频悬浮窗怎么开启 边看视频边操作其他应用教程
Laravel表单请求验证类怎么用_Laravel Form Request分离验证逻辑教程
Laravel如何使用Collections进行数据处理?(实用方法示例)
消息称 OpenAI 正研发的神秘硬件设备或为智能笔,富士康代工
Laravel怎么调用外部API_Laravel Http Client客户端使用
青岛网站建设如何选择本地服务器?
如何在阿里云部署织梦网站?
MySQL查询结果复制到新表的方法(更新、插入)
Laravel如何使用Blade组件和插槽?(Component代码示例)
Laravel的路由模型绑定怎么用_Laravel Route Model Binding简化控制器逻辑
深圳网站制作平台,深圳市做网站好的公司有哪些?
Win11怎么查看显卡温度 Win11任务管理器查看GPU温度【技巧】
Laravel如何从数据库删除数据_Laravel destroy和delete方法区别
iOS正则表达式验证手机号、邮箱、身份证号等
大学网站设计制作软件有哪些,如何将网站制作成自己app?
Laravel如何为API编写文档_Laravel API文档生成与维护方法
Laravel Blade模板引擎语法_Laravel Blade布局继承用法
如何在不使用负向后查找的情况下匹配特定条件前的换行符
香港服务器网站搭建教程-电商部署、配置优化与安全稳定指南
Laravel队列任务超时怎么办_Laravel Queue Timeout设置详解

