【Java】Java中类的初始化顺序(静态方法,静态块,非静态块,最后有流程图)

📝个人主页:哈__
期待您的关注

目录
一、无继承关系类的初始化
1、静态变量k被初始化
2、静态变量t1初始化
3、静态变量 t2初始化
4、静态变量i初始化
5、静态变量n初始化
6、静态块初始化
7、非静态块初始化
8、非静态属性初始化
9、执行构造方法
二、有父类继承的初始化
在日常使用Java的时候,我们都接触过new这个关键字,那你是否知道在我们的对象真正创建出来之前都做了哪些事情呢?
实际上要去判断一个类的初始化的顺序,需要分一下情况,一种是没有继承关系的类(不考虑Object类),一种是有继承关系的类。
一、无继承关系类的初始化
先看下边的代码。有着这样的一个类InitializeDemo ,我们直接运行main方法,你知道会打印出来什么吗?
public class InitializeDemo {private static int k = 1;private static InitializeDemo t1 = new InitializeDemo("t1");private static InitializeDemo t2 = new InitializeDemo("t2");private static int i = print("i");private static int n = 99;{print("初始化块");j=100;}public InitializeDemo(String str){System.out.println((k++)+":" + str + " i="+i+". n="+n);++i;++n;}static{print("静态块");n=100;}private int j = print("j");public static int print(String str){System.out.println((k++)+":" + str + " i="+i+". n="+n);++n;return ++i;}public static void main(String[] args) {InitializeDemo i = new InitializeDemo("test");}
}
打印结果如下所示。

想要弄明白这个,我就得先了解一下类的生命周期了。我们通过主方法运行Java程序,而这个主方法中创建了i对象并且属于InitializeDemo 类,所以在main方法执行时会将我们的类进行初始化。
在我们的类第一次进行初始化的时候,我们类中的静态块和静态属性会被优先构建。之后才轮得到非静态块和非静态属性。
当你知道了上边的规则之后,我们来看代码,类中有五个静态属性,一个非静态属性,一个静态块,一个非静态块还有一个静态方法。我们优先构建静态方法、属性和静态块,之后在构建非静态块。
这里我总结出第一条规则。
类的一个对象进行初始化,按照代码顺序从上往下先构建静态的属性、方法和静态块,之后在构建非静态块和非静态属性。(类中的静态块和静态变量只会初始化一次,也就是类第一次被用到的时候)
1、静态变量k被初始化
private static int k = 1;
2、静态变量t1初始化
private static InitializeDemo t1 = new InitializeDemo("t1");
这里还要说一下,这个静态变量是创建自己的类的对象,代码执行到这一行就要进行一个对象的初始化过程了。遇到这种创建本类对象的,我们按照以下的第二条规则。
一个类中有静态的本类对象,创建的过程从上到下先执行本类的非静态块和非静态属性,最后在执行构造方法。
那么我们初始化t1的时候,就要从上向下找非静态块和非静态属性(如果有的话 ),最后在执行构造方法。
{print("初始化块");j=100;}
我们调用print函数并且将j的值修改为100,这样就出现了我们的第一行。
之后往下走,走到了这一行代码。这行代码定义了j变量,并且调用了print方法,所以也就有了我们的第二行。
private int j = print("j");
最后调用构造方法。打印我们的第三行。
现在你是否清楚了前三行输出结果是怎么来的了吗?这前三行的结果都是t1进行初始化时非静态块和非静态变量的执行结果。
3、静态变量 t2初始化
搞明白了t1是如何初始化的t2就和t1一模一样了,这里不讲解。
4、静态变量i初始化
静态变量i的初始化用到了print函数,这也就是第七行为什么会打印的原因。
private static int i = print("i");
5、静态变量n初始化
private static int n = 99;
6、静态块初始化
这里调用print函数,也就是第八行的由来。
static{print("静态块");n=100;}
ok,到了这一步我们的静态属性和静态块已经从上到下全部初始化完成了。但你要知道,我们在上边初始化的非静态块和非静态属性所打印的语句是我们的t1和t2对象引起的,并非我们主方法内构建的i对象引起的,接下来还要初始化我们的非静态块和属性。
7、非静态块初始化
第九行的由来。
{print("初始化块");j=100;}
8、非静态属性初始化
第十行的由来。
private int j = print("j");
9、执行构造方法
第十一行的由来。
public InitializeDemo(String str){System.out.println((k++)+":" + str + " i="+i+". n="+n);++i;++n;}
以上就是我们的一个类的构建过程,这里我给大家一张图(自己画的)。

这里需要注意以下,非静态属性如果创建的是自己的本类对象的话,那么会报错的。原理也很简单,就是一个循环创建的过程导致栈溢出。

二、有父类继承的初始化
和没有父类继承初始化大同小异,我定义了这样的一个类让InitializeDemo,去继承。为了便于还是懵懂的同学理解,我把静态变量t1和t2删掉。
public class InitializeDemoFather {{System.out.println("父类初始化块");}static{System.out.println("父类静态块");}public InitializeDemoFather(){System.out.println("父类构造函数");}
}
来看看我们现在的打印结果。

我给大家讲一下初始化的顺序大家就明白了,这里用一张图来表示。

对应着上边的图,是不是一看就有点思路了呢?
如果你可以完整的走出以上的输出顺序,你就可以把t1和t2对象加上去了,不过不要被输出顺序所迷惑,就比如说,你可能会看到父类静态块和属性初始化完成后,初始化的不是子类的静态块和静态属性,而是父类的非静态块和非静态属性。你应该认真的思考一下,这个 输出的父类的非静态块和非静态属性初始化的语句到底是从何而来?
相关文章:
【Java】Java中类的初始化顺序(静态方法,静态块,非静态块,最后有流程图)
📝个人主页:哈__ 期待您的关注 目录 一、无继承关系类的初始化 1、静态变量k被初始化 2、静态变量t1初始化 3、静态变量 t2初始化 4、静态变量i初始化 5、静态变量n初始化 6、静态块初始化 7、非静态块初始化 8、非静态属性初始化 9、执行构造…...
在RK3588开发板使用FFMpeg 结合云服务器加SRS实现摄像头数据推流到云端拱其他设备查看
今天测试了一把在开发板把摄像头数据推流到云端服务器,然后给其他电脑通过val软件拉取显示摄像头画面,浅浅记录一下大概步骤 1.开发板端先下载ffmpeg apt install ffmpeg2.云服务器先安装SRS的库 云服务器我使用ubuntu系统,SRS是个什么东西&…...
elasticsearch搭建教程
主要参看这里就行,需要特别注意其中报错的解决方案:搭建elasticsearch 单机节点里,按照上述教程搭建只能开放本地访问,如果需要其他机器访问,需要在elasticsearch.yml里新增几个配置: node.name: node-1 network.host…...
c++ 归并排序
归并排序是一种遵循分而治之方法的排序算法。它的工作原理是递归地将输入数组划分为较小的子数组并对这些子数组进行排序,然后将它们合并在一起以获得排序后的数组。 简单来说,归并排序的过程就是将数组分成两半,对每一半进行排序,…...
基于vs和C#的WPF应用之动画3
注:1、在内部和外部使用缓动函数 <Grid.Resources> <PowerEase x:Key"powerease" Power"3" EasingMode"EaseInOut"/> </Grid.Resources> <DoubleAnimation EasingFunction"{StaticResource powerease}&quo…...
Python import 必看技巧:打造干净利落的代码结构
大家好,学习Python你肯定绕不过一个概念import,它是连接不同模块的桥梁,是实现代码复用和模块化的关键。本文将带你深入探索Python中import的原理,并分享一些实用的导入技巧。 1. import 原理 导入机制概述 在Python中,模块(module)是一种封装Python代码的方式,它允许…...
计算机视觉(CV)(Computer Vision)
计算机视觉技术(Computer Vision),解决的是什么? 图片和视频是非结构化数据,机器如果要理解某一图片或视频表达的内容,是无法直接分析的,这种情况,就需要有计算机视觉技术ÿ…...
python:画折线图
import pandas as pd import matplotlib.pyplot as plt from matplotlib.font_manager import FontProperties# 设置新宋体字体的路径 font_path D:/reportlab/simsun/simsun.ttf# 加载新宋体字体 prop FontProperties(fnamefont_path)""" # 读取 xlsx 文件 d…...
Spring Data JPA 与 MyBatisPlus的比较
前言 JPA(Java Persistence API)和MyBatis Plus是两种不同的持久化框架,它们具有不同的特点和适用场景。 JPA是Java官方的持久化规范,它提供了一种基于对象的编程模型,可以通过注解或XML配置来实现对象与数据库的映射…...
【C++】STL-list的使用
目录 1、list的使用 1.1 list的构造 1.2 list的遍历 1.3 list capacity 1.4 list element access 1.5 容量相关 list是一个带头双向循环链表 1、list的使用 1.1 list的构造 1.2 list的遍历 list只有两种遍历方式,因为没有operator[] 因为list的双向链表&am…...
进度条(小程序)
缓冲区的概念 缓冲区是内存中的一个临时存储区域,用来存放输入或输出数据。在标准 I/O 库中,缓冲区的使用可以提高数据处理的效率。例如,当向终端输出文本时,字符通常存储在缓冲区中,直到缓冲区满或者遇到特定条件时才…...
PyCharm安装教程(超详细图文教程)
一、下载和安装 1.进入PyCharm官方下载,官网下载地址: https://www.jetbrains.com/pycharm/download/ 专业版安装插件放网盘了,网盘下载即可:itcxy.xyz/229.html2.安装 1.下载后找到PyCharm安装包,然后双击双击.ex…...
金蝶BI应收分析报表:关于应收,这样分析
这是一张出自奥威-金蝶BI方案的BI应收分析报表,是一张综合运用了筛选、内存计算等智能分析功能以及数据可视化图表打造而成的BI数据可视化分析报表,可以让企业运用决策层快速知道应收账款有多少?账龄如何?周转情况如何?…...
salmon使用体验
文章目录 salmon转录本定量brief模式一:fastq作为输入文件需要特别注意得地方 模式二: bam文件作为输入 salmon转录本定量 brief 第一点是,通常说的转录组分析其中有一项是转录本定量,这是一个很trick的说话,说成定量…...
Ubuntu 20.04 安装 Ansible
使用官方的 Ubuntu PPA 更新包列表: apt update安装软件属性常用命令 apt install software-properties-common添加 Ansible PPA 到系统: add-apt-repository --yes --update ppa:ansible/ansible再次更新包列表以包括新添加的 PPA: apt …...
TypeScript学习笔记:强类型JavaScript的优雅之旅
在前端开发领域,JavaScript以其灵活性和广泛的支持度成为无可争议的王者。然而,随着项目规模的增长,JavaScript的动态类型特性开始暴露出一些问题,比如代码的可维护性、类型错误难以提前发现等。为了解决这些问题,Micr…...
监控异地组网怎么组网?
监控异地组网是指在不同地域的网络环境下,实现对监控设备的远程访问和管理。在传统的网络环境下,由于网络限制和设备配置等问题,监控设备的远程访问往往受到一定的限制和困扰。为了解决这个问题,引入了天联组网技术,实…...
将本地托管模型与 Elastic AI Assistant 结合使用的好处
作者:来自 Elastic James Spiteri, Dhrumil Patel 当今公共部门组织利用生成式人工智能解决安全挑战的一种方式。 凭借其筛选大量数据以发现异常模式的能力,生成式人工智能现在在帮助团队保护其组织免受网络威胁方面发挥着关键作用。 它还可以帮助安全专…...
Linux的内核态和用户态
一、Linux操作系统运行在两种不同的运行模式下:内核态(Kernel Mode)和用户态(User Mode) 内核态(Kernel Mode): 内核态也称为特权模式或系统模式,是操作系统内核执行代码…...
springboot利用Redis的Geo数据类型,获取附近店铺的坐标位置和距离列表
文章目录 GEO介绍GEO命令行应用添加地理坐标位置获取指定单位半径的全部地理位置列表springboot 的实际应用 GEO介绍 在Redis 3.2版本中,新增了一种数据类型:GEO,它主要用于存储地理位置信息,并对存储的信息进行操作。 GEO实际上…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
线程同步:确保多线程程序的安全与高效!
全文目录: 开篇语前序前言第一部分:线程同步的概念与问题1.1 线程同步的概念1.2 线程同步的问题1.3 线程同步的解决方案 第二部分:synchronized关键字的使用2.1 使用 synchronized修饰方法2.2 使用 synchronized修饰代码块 第三部分ÿ…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
今日科技热点速览
🔥 今日科技热点速览 🎮 任天堂Switch 2 正式发售 任天堂新一代游戏主机 Switch 2 今日正式上线发售,主打更强图形性能与沉浸式体验,支持多模态交互,受到全球玩家热捧 。 🤖 人工智能持续突破 DeepSeek-R1&…...
ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
SAP学习笔记 - 开发26 - 前端Fiori开发 OData V2 和 V4 的差异 (Deepseek整理)
上一章用到了V2 的概念,其实 Fiori当中还有 V4,咱们这一章来总结一下 V2 和 V4。 SAP学习笔记 - 开发25 - 前端Fiori开发 Remote OData Service(使用远端Odata服务),代理中间件(ui5-middleware-simpleproxy)-CSDN博客…...
