【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实际上…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
STM32+rt-thread判断是否联网
一、根据NETDEV_FLAG_INTERNET_UP位判断 static bool is_conncected(void) {struct netdev *dev RT_NULL;dev netdev_get_first_by_flags(NETDEV_FLAG_INTERNET_UP);if (dev RT_NULL){printf("wait netdev internet up...");return false;}else{printf("loc…...
【磁盘】每天掌握一个Linux命令 - iostat
目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat(I/O Statistics)是Linux系统下用于监视系统输入输出设备和CPU使…...

P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...

3-11单元格区域边界定位(End属性)学习笔记
返回一个Range 对象,只读。该对象代表包含源区域的区域上端下端左端右端的最后一个单元格。等同于按键 End 向上键(End(xlUp))、End向下键(End(xlDown))、End向左键(End(xlToLeft)End向右键(End(xlToRight)) 注意:它移动的位置必须是相连的有内容的单元格…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...

以光量子为例,详解量子获取方式
光量子技术获取量子比特可在室温下进行。该方式有望通过与名为硅光子学(silicon photonics)的光波导(optical waveguide)芯片制造技术和光纤等光通信技术相结合来实现量子计算机。量子力学中,光既是波又是粒子。光子本…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析
Java求职者面试指南:Spring、Spring Boot、MyBatis框架与计算机基础问题解析 一、第一轮提问(基础概念问题) 1. 请解释Spring框架的核心容器是什么?它在Spring中起到什么作用? Spring框架的核心容器是IoC容器&#…...