【Java18】初始化块

初始化块构造器、成员变量、成员方法一起,是唯四能在类中出现的成员。

  • 初始化块的作用和构造器类似,目的是对对象进行初始化操作;
  • 一个类中可以有多个初始化块;
  • 初始化块只有两种修饰方式:staticdefault。用static修饰的叫类初始化块,没有修饰符的叫实例初始化块
  • 类初始化块先于实例初始化块执行。同样的修饰符,位置在前的初始化块先执行。

虽然但是,同样修饰符的代码块没必要分成一个个小块块。因为代码块就是在创建Java对象的时候隐式执行的,而且总是全部执行。所以分成小块块和合并成一个大块块,没有区别。

实例初始化块
public class Person
{// 实例初始化块{var a = 6;if (a > 4){System.out.println("Person实例初始化块:局部变量a的值大于4");}System.out.println("Person的实例初始化块");}// 第二个实例初始化块{System.out.println("Person的第二个实例初始化块");}public Person(){System.out.println("Person的无参数构造器");}public static void main(String[] args){new Person();}
}

初始化块没有名字,所以无法通过显式手段调用它。它就在创建Java对象的时候隐式执行。

  1. 实例初始化块只在创建Java对象的时候隐式执行,且在构造器之前执行;
  2. 类初始化块在类初始化阶段隐式执行。
public class InstanceInitTest
{// 实例初始化块{a = 6;}int a = 9;public static void main(String[] args){System.out.println(new InstanceInitTest().a);}
}

最终输出结果是9.

Why?

  1. 代码没有报错,第5行中的a的类型由第7行决定,这是编译时确定的,a是InstanceInitTest类的成员变量;
  2. 实力初始化块在其他语句之前执行。因此,a首先赋值为6,然后执行成员变量声明语句,再次被赋值为9。

Java创建对象的过程

  1. 第一次创建某个类的对象时,要先加载类(为类成员变量、类方法,以及类代码块分配内存);
  2. 其余时刻,首先为该对象的所有实例变量分配空间;
  3. 接着,对实例变量进行初始化。
  4. 初始化顺序是:
    1. 实例初始化块或声明实例变量时指定的初始值;
    2. 构造器中指定的初始值。

对上面的代码,如果调换初始化块和成员变量声明语句的顺序,结果会改变:

public class InstanceInitTest
{int a = 9;// 实例初始化块{a = 6;}public static void main(String[] args){System.out.println(new InstanceInitTest().a);}
}

输出结果会变成6.

初始化块和构造器的异同

  1. 实力初始化块总是在构造器执行之前执行;
  2. 实例初始化块没法接受外部参数,因此它所能执行的初始化处理对于该类的所有对象都只能是相同的。

由此可以倒推出实例初始化块的作用:当有一段实例变量初始化代码完全相同,且不需要外部传参时,可以把这段代码放到实力初始化块中,方便代码阅读;

此外,多个构造器中不需要外部传参的操作,如果有相同的,也可以提取出来放到实例代码块中,以提升代码复用水平。

实例初始化块其实是个假象。使用javac编译Java类后,该类中的实例初始化块会消失:里面的代码会“回归”到每个构造器中,且位于构造器中代码的最前面。

在这里插入图片描述

类初始化块

类初始化块通常用于对类变量执行初始化处理。类初始化块不能对实例变量进行初始化。

类初始化块回向上追溯,先执行父类的类初始化块,依次往下。

class Root
{static{System.out.println("Root的类初始化块");}{System.out.println("Root的实例初始化块");}
}class Mid extends Root
{static {System.out.println("Mid的类初始化块");}{System.out.println("Mid的实例初始化块");}public Mid(){System.out.println("Mid的无参数构造器");}public Mid(String msg){// 通过this调用无参数构造器this();System.out.println("Mid的带参数构造器,参数值: " + msg);}
}class Leaf extends Mid
{static {System.out.println("Leaf的类初始化块");}{System.out.println("Leaf的实例初始化块");}public Leaf(){// 通过super调用父类中有一个String参数的构造器super("疯狂Java讲义");System.out.println("执行Leaf的构造器");}
}public class InstanceInitTest
{public static void main(String[] args){new Leaf();new Leaf();}
}
  • 这段代码描述了三个类的继承关系,从父类到子类依次是:Root–>Mid–>Leaf
  • main中,第一次执行new Leaf(),是第一次加载类。此时系统中不存在Leaf类,所以要先加载并初始化Leaf类。这是就会
    • 先执行类初始化块。这部分又会遵循回溯机制,先执行父类的类初始化块,再往下依次执行。因此会出现先执行Root的类初始化块,然后是Mid的类初始化块,最后是Leaf的类初始化块。
    • 接着,执行实例初始化块和构造器。注意,前面说过实例初始化块其实就是构造器的一部分。所以这里会先执行Root的实例初始化块+构造器,然后是Mid的实例初始化块+构造器,最后是Leaf的实例初始化块+构造器。
  • 第二次执行new Leaf()时,就不会再进行类初始化了。

类初始化块和声明类变量(static修饰)的初始化代码和上面说过的实例初始化一样,按顺序执行。

public class StaticInitTest
{// 先执行类初始化块,将a赋值为6static {a = 6;}// 再将a类变量赋值为9static int a = 9;public static void main(String[] args){// 下面的代码将输出9System.out.println(StaticInitTest.a);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/46689.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

nginx生成自签名SSL证书配置HTTPS

一、安装nginx nginx必须有"--with-http_ssl_module"模块 查看nginx安装的模块: rootecs-7398:/usr/local/nginx# cd /usr/local/nginx/ rootecs-7398:/usr/local/nginx# ./sbin/nginx -V nginx version: nginx/1.20.2 built by gcc 9.4.0 (Ubuntu 9.4.0…

Android Studio - adb.exe已停止运作的解决方案

adb.exe 是Android Debug Bridge 的缩写,它是Android SDK 中的一个调试工具,允许开发者通过命令行界面与设备进行交互,执行各种操作,如运行设备的shell、管理模拟器或设备的端口映射、在计算机和设备之间上传/下载文件、将本地APK…

我的GeneFace++部署与运行之旅

文章目录 引言项目背景概述重要性分析结论 环境准备1. 安装CUDA2. 安装Python依赖3. 准备3DMM模型(BFM2009)及其他数据 运行官方 Demo训练自己的视频数据准备训练推理测试 遇到的问题与解决方案问题一:cuda 安装完发现版本不对问题二&#xf…

C语言 底层逻辑详细阐述结构体 #结构体的声明 #结构体的初始化 #结构体成员访问 #结构体传参

文章目录 前言 一、结构体的基础知识 二、结构体的初始化 1、结构体类型声明: 2、结构体成员的类型 3、结构体变量的初始化: 三、结构体成员访问 四、结构体传参 总结 前言 基于自我理解的角度来讲结构体; 一、结构体的基础知识 结构是一些…

NSSCTF中24网安培训day2中web题目

[SWPUCTF 2021 新生赛]ez_unserialize 这道题目考察php反序列化的知识点 打开题目,发现没有提示,我们试着用御剑扫描目录文件,发现存在robots.txt的文件 接着访问这个文件,发现是一段php反序列化代码,我们需要进行序…

论文翻译:通过云计算对联网多智能体系统进行预测控制

通过云计算对联网多智能体系统进行预测控制 文章目录 通过云计算对联网多智能体系统进行预测控制摘要前言通过云计算实现联网的多智能体控制系统网络化多智能体系统的云预测控制器设计云预测控制系统的稳定性和一致性分析例子结论 摘要 本文研究了基于云计算的网络化多智能体预…

【常见开源库的二次开发】基于openssl的加密与解密——Base58比特币钱包地址——算法分析(三)

目录: 目录: 一、base58(58进制) 1.1 什么是base58? 1.2 辗转相除法 1.3 base58输出字节数: 二、源码分析: 2.1源代码: 2.2 算法思路介绍: 2.2.1 Base58编码过程: 2.1.2 Base58解码过…

Leetcode—146. LRU 缓存【中等】(shared_ptr、unordered_map、list)

2024每日刷题(143) Leetcode—146. LRU 缓存 先验知识 list & unordered_map 实现代码 struct Node{int key;int value;Node(int key, int value): key(key), value(value) {} };class LRUCache { public:LRUCache(int capacity): m_capacity(capa…

实战案例:用百度千帆大模型API开发智能五子棋

前随着人工智能技术的迅猛发展,各种智能应用层出不穷。五子棋作为一款经典的棋类游戏,拥有广泛的爱好者。将人工智能技术与五子棋结合,不仅能提升游戏的趣味性和挑战性,还能展现AI在复杂决策问题上的强大能力。在本篇文章中&#…

habase集群安装

解压到/opt/softs目录 tar -zxvf hbase-2.4.11-bin.tar.gz -C /opt/softs/ 改名 mv hbase-2.4.11/ hbase2.4.11 配置环境变量 修改/etc/profile vim /etc/profile 添加 #HBASE_HOME export HBASE_HOME/opt/softs/hbase2.4.11 export PATH$PATH:$HBASE_HOME/bin 修改其中的…

怎么把自己写的组件发布到npm官方仓库??

一.注册npm账号 npm官网 1.注册npm 账号 2.登陆 3.登陆成功 二.搭建一个vue 项目 具体步骤参考liu.z Z 博客 或者初始化一个vue项目 vue create XXX (工程名字)运行代码 npm run serve三.组件封装 1.在src文件下建一个package文件&#xff0…

借助 Aspose.Words,在 C# 中将 Word 转换为 JPG

有时我们需要将 Word 文档转换为图片,因为 DOC 或 DOCX 文件在不同设备上的显示可能会有所不同,但图像(例如 JPG 格式)在任何地方看起来都一样。 Aspose.Words 是一种高级Word文档处理API,用于执行各种文档管理和操作…

【OrangePi AIpro】: 探索AI加成的开源硬件魅力

🌈个人主页: 鑫宝Code 🔥热门专栏: 闲话杂谈| 炫酷HTML | JavaScript基础 ​💫个人格言: "如无必要,勿增实体" 文章目录 Orange Pi: 探索开源硬件的魅力引言Orange Pi概述OrangePi AIPro产品介绍试用体…

—张pdf怎么分割成多页,怎么把一个pdf分割

在数字化时代,pdf文件已经成为我们工作和生活中不可或缺的一部分。然而,有时候我们可能会遇到需要将一张pdf文件分割成多页的情况。无论是为了便于分享,还是为了满足特定的文档格式要求,这个任务都可能变得相当棘手。但别担心&…

zookeeper+kafka消息队列群集部署

一、消息队列 1.消息队列 消息是应用间传送的数据 消息队列是应用见的通信方式,消息发送后立即返回,由消息系统确保消息可靠传递。消息发布者只管把消息发布到 MQ 中而不用管谁来取,消息使用者只管从 MQ 中取消息而不管是谁发布的。这样发…

设计模式学习(二)工厂模式——抽象工厂模式+注册表

设计模式学习(二)工厂模式——抽象工厂模式注册表 前言使用简单工厂改进使用注册表改进参考文章 前言 在上一篇文章中我们提到了抽象工厂模式初版代码的一些缺点:①客户端违反开闭原则②提供方违反开闭原则。本文将针对这两点进行讨论 使用…

CSS-0_3 CSS和单位

文章目录 CSS的值和单位属性值长度单位CSS和绝对单位CSS和相对单位百分比em & rem视口 颜色单位 碎碎念 CSS的值和单位 我们知道,CSS是由属性和属性值所组成的表 随着CSS的发展,属性不说几千也有几百,我从来不支持去背诵所有的可能性。…

昇思25天学习打卡营第22天|基于MindSpore的红酒分类实验

基于MindSpore的红酒分类实验 K近邻算法实现红酒聚类 1、实验目的 了解KNN的基本概念;了解如何使用MindSpore进行KNN实验。 2、K近邻算法原理介绍 K近邻算法(K-Nearest-Neighbor, KNN)是一种用于分类和回归的非参数统计方法,…

WPF 手撸插件 一

1、本文主要使不适用第三方工具,纯手工的WPF主项目加载另一个WPF的项目,这里我们加载的是*.exe。 2、项目结构如下图。AbstractionLayer用于创建插件的接口。WPFIPluginDemo是主程序。WpfPlugin3是要加载的插件程序。 3、 AbstractionLayer中添加接口IP…

jvm常用密令、jvm性能优化、jvm性能检测、Java jstat密令使用、Java自带工具、Java jmap使用

1.jps是Java虚拟机的进程状态工具,用于列出正在运行的Java进程 jps命令的使用:cmd打开直接jps 1.1不带参数: jps 默认情况下,列出所有正在运行的 Java 进程的进程 ID 和主类名。 1.2 -l:显示完整的主类名或 JAR 文件…