详解Java中的实例初始化块(IIB)
在 Java 语言中的类初始化块 文章中我们简单的介绍了下 Java 中的实例初始化块 ( IIB )。不过我觉得介绍的有点简单了,于是,再写一篇文章详细介绍下吧。
Java 语言中,存在三种操作:方法 、构造函数 和 初始化块。
其中初始化块又分为 实例初始化块 ( IIB ) 和 静态初始化块。本章节,我们主要介绍实例初始化块。
实例初始化块 用于初始化实例变量。
实例初始化块 会在初始化类的一个实例时执行,而且在构造函数之前就执行。并且每次创建类的对象时它们都会执行。
实例化块的语法
实例初始化块一般放在构造函数之前,使用大括号 {} 扩起来的代码。语法结构一般如下
class JavaTester { // 实例化块 { System.out.println("IIB block"); } // 构造函数 JavaTester() { System.out.println("Constructor Called"); } public static void main(String[] args) { JavaTester a = new JavaTester(); } }
注意,实例化块并不是类的必须。只是一个可选项。用于抽出构造函数的公共部分单独执行而已。
这段代码是可以编译运行的,运行结果如下
[yufei@www.twle.cn java]$ javac JavaTester.java && java JavaTester IIB block Constructor Called
一个类中包含多个实例初始化块
类中的 实例初始化块 并不是类所必须的,而且,不限数量。一个类既可以没有实例初始化块,也可以有多个实例初始化块。
如果一个类有多个实例初始化块,那么它们会按照顺序从上到下依次执行,也就是说,定义在类顶部的实例初始化块最先执行。
我们来看一段代码,下面的类 JavaTester 定义了多个实例初始化块。
class JavaTester { { System.out.println("IIB1 block 1 "); } { System.out.println("IIB2 block 2"); } JavaTester() { System.out.println("Constructor Called"); } { System.out.println("IIB3 block 3"); } public static void main(String[] args) { JavaTester a = new JavaTester(); } }
运行上面这段代码,输出结果如下
[yufei@www.twle.cn java]$ javac JavaTester.java && java JavaTester IIB1 block 1 IIB2 block 2 IIB3 block 3 Constructor Called
父类中的初始化块
在 Java 语言的继承体系中,父类同样可以有初始化块,而且数量不限。
父类的实例初始化块在子类的构造函数中调用 super() 之后立即运行。编译器会在执行当前类的实例初始化块之前先执行父类的实例初始化块。
是不是很绕口,我们写一段代码来演示下
class B { B() { System.out.println("B-Constructor Called"); } { System.out.println("B-IIB block"); } } public class JavaTester extends B { { System.out.println("JavaTester IIB1 block 1 "); } { System.out.println("JavaTester IIB2 block 2"); } JavaTester() { super(); System.out.println("JavaTester-Constructor Called"); } { System.out.println("JavaTester IIB3 block 3"); } public static void main(String[] args) { JavaTester a = new JavaTester(); } }
运行以上范例,输出结果如下
[yufei@www.twle.cn java]$ javac JavaTester.java && java JavaTester B-IIB block B-Constructor Called JavaTester IIB1 block 1 JavaTester IIB2 block 2 JavaTester IIB3 block 3 JavaTester-Constructor Called
从运行的结果来看,当创建类 JavaTester 的对象时,编译器尝试执行类 JavaTester 的构造函数。但因为它有一个父类,在发现了 super() 语句后,就转而先执行父类的构造函数。
因此,在继承体系中,实例初始化块和构造函数的执行顺序如下
执行父类的实例初始化块
执行父类的构造函数
执行当前类的实例初始化块
执行当前类的构造函数
实例初始化块的要点
我们一起来回顾下实例初始化块的要点。
每次创建新实例时都会运行实例初始化块
初始化块按它们在类中出现的顺序运行
如果存在父类,则首先会实例化父类然后在调用当前类的实例初始化块,最后再调用当前类的构造函数。
相关文章
slf4j与jul、log4j1、log4j2、logback的集成原理
这篇文章主要介绍了slf4j与jul、log4j1、log4j2、logback的集成原理,以及通用日志框架与具体日志实现系统的机制机制介绍,包括依赖的jar包,jar冲突处理等2022-03-03浅析Java常用API(Scanner,Random)匿名对象
这篇文章主要介绍了Java常用API(Scanner,Random)匿名对象,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧2019-03-03Java动态线程池插件dynamic-tp集成zookeeper
ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等2023-03-03如何解决Mybatis-plus中@TableLogic注解失效问题
这篇文章主要介绍了如何解决Mybatis-plus中@TableLogic注解失效问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教2024-05-05
最新评论