Java——对象初始化顺序使用详解
作者:lim_dev 发布时间:2023-11-01 01:08:46
一、 代码块的概念
在探究对象初始化顺序之前,我们先通过代码来了解一下代码块的概念。
class Test{
public static String str1; //静态字段
public String str2; //普通字段
static{
//静态代码块
}
{
//构造代码块
}
public Test() {
//构造函数
}
}
二、 创建子类对象时,对象的初始化顺序
1. 字段初始化、代码块和构造函数的执行顺序
我们先看代码和结果
public class CodeBlockTest {
public static void main(String[] args) {
Child child = new Child();
}
}
class Father {
public static String fatherStr1 = "fatherStr1(静态字段初始化值)";
public String fatherStr2 = "fatherStr2(字段初始化值)";
static {
System.out.println("父类静态代码块:" + fatherStr1);
fatherStr1 = "fatherStr1(静态代码块赋值)";
}
{
System.out.println("父类构造代码块:" + fatherStr2);
fatherStr2 = "fatherStr2(构造代码块赋值)";
}
public Father() {
System.out.println("父类构造函数块:" + fatherStr2);
fatherStr2 = "fatherStr2(构造函数赋值)";
}
}
class Child extends Father {
public static String childStr1 = "childStr1(静态字段初始化值)";
public String childStr2 = "childStr2(字段初始化值)";
static {
System.out.println("子类静态代码块:" + childStr1);
childStr1 = "childStr1(静态代码块赋值)";
}
{
System.out.println("子类构造代码块:" + childStr2);
childStr2 = "childStr2(构造代码块赋值)";
}
public Child() {
System.out.println("子类构造函数:" + childStr2);
childStr2 = "childStr2(构造函数赋值)";
}
}
// 输出结果:
// 父类静态代码块:fatherStr1(静态字段初始化值)
// 子类静态代码块:childStr1(静态字段初始化值)
// 父类构造代码块:fatherStr2(字段初始化值)
// 父类构造函数块:fatherStr2(构造代码块赋值)
// 子类构造代码块:childStr2(字段初始化值)
// 子类构造函数:childStr2(构造代码块赋值)
通过每执行一个代码块或构造函数,输出字段在上一代码块执行后的值,以此来探究对象的初始化顺序。
由目前的输出结果可知,对于对象的初始化顺序,我们可以得出以下结论:
1. 父类静态字段初始化
2. 父类静态代码块、子类静态字段初始化 (接下来探究两者的顺序)
3. 子类静态代码块
4. 父类普通字段初始化
5. 父类构造代码块
6. 父类构造函数
7. 子类普通字段初始化
8. 子类构造代码块
9. 子类构造函数
2. 父类静态代码块和子类静态字段初始化的执行顺序
还是一样,我们通过代码的执行结果来探究两者间的执行顺序。
public class CodeBloacTest2 {
public static void main(String[] args) {
Child child = new Child();
}
}
class Father {
public static String fatherStr = "(静态字段初始化值)";
static {
System.out.println("父类静态代码块:fatherStr" + fatherStr);
fatherStr = "(静态代码块赋值)";
}
}
class Child extends Father {
public static String childStr = fatherStr;
static {
System.out.println("子类静态代码块:childStr = fatherStr" + childStr);
childStr = "(静态代码块赋值)";
}
}
// 输出结果:
// 父类静态代码块:fatherStr(静态字段初始化值)
// 子类静态代码块:childStr = fatherStr(静态代码块赋值)
我们在子类静态字段childStr初始化的时候,赋的是父类静态字段fatherStr的值。由输出结果可知,childStr初始化后的值是父类静态代码块执行后赋予fatherStr的值。由此可知两者的执行顺序为:父类静态代码块==>子类静态字段初始化
三、 结论
父类静态字段初始化
父类静态代码块
子类静态字段初始化
子类静态代码块
父类普通字段初始化
父类构造代码块
父类构造函数
子类普通字段初始化
子类构造代码块
子类构造函数
通过结论我们可以很明显的看出:static字段、代码块的执行顺序优先于非static字段、代码块。这是因为在静态域是属于类的,在类加载后就一直存在;而普通域需要创建对象才能访问。而在创建对象时,需要先加载父类,然后再加载子类,因此父类的静态字段初始化和静态代码块执行先于子类。
以上内容希望对各位朋友有所帮助
来源:http://blog.csdn.net/lim_dev/article/details/70161726


猜你喜欢
- 第 1 步:将这个 Spring Boot 项目的打包方式设置为 war。<packaging>war</packagin
- spring注入枚举类型作为参数//定义枚举类型public enum ReportType { MONTH,WE
- MSMQ (Microsoft消息队列)是Windows中默认可用的消息队列。作为跨计算机系统发送和接收消息的可靠方法,MSMQ提供了一个可
- 在android中,LayoutInflater有点类似于Activity的findViewById(id),不同的是LayoutInfla
- Java进阶之FileUpload完成上传的实例 FileUpload是Apache commons下面
- 有的时候,我们需要对一堆数据进行统计分析后生成HTML或Excel格式报表。本来这并不是一件很难的事,但确是件比较麻烦的事情。最令人头痛的是
- 基于 springboot+vue 的测试平台(练手项目)开发继续更新。接下来准备开发请求断言功能。关于这个功能要实现哪些需求,长什么样子,
- Java泛型映射不同的值类型详解前言:一般来说,开发人员偶尔会遇到这样的情形: 在一个特定容器中映射任意类型的值。然而Java 集合API只
- 本文介绍了Android多渠道打包的方法步骤,分享给大家,具体如下:1.生成签名文件点击 Build -> Generate Sign
- 本文实例为大家分享了java实现文件下载的具体代码,供大家参考,具体内容如下public HttpServletResponse downl
- 本文就是会将数组里面的单词进行倒序排列 例如 how old are you -> you are old how示例程序输出结果:t
- 目录一、概述二、环境配置及代码步骤1. 环境配置2. 代码步骤一、概述PDF打印小册子是指将PDF格式文档在打印成刊物前需要提前进行的页面排
- import java.awt.*; import java.util.*; import javax.swing.*; public cl
- Java中的多线程是一种抢占式的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。 共同点: 1. 他们
- 这篇文章主要介绍了Java实现TCP/IP协议的收发数据(服务端)代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参
- 前言重试,我相信大家并不陌生。在我们调用Http接口的时候,总会因为某种原因调用失败,这个时候我们可以通过重试的方式,来重新请求接口。生活中
- 下文我们介绍两种双击事件拦截的方式1.通过Android的事件分发机制进行拦截(dispatchTouchEvent)话不多说,直接上代码:
- 1.概述本篇文章仅是Android小白在写一个小程序,内容仅供参考,有很多不足之处希望各位大神指出,文章末尾有整个项目的下载,不需要币,只求
- JVM内存组成结构JVM栈由堆、栈、本地方法栈、方法区等部分组成,结构图如下所示:1)堆所有通过new创建的对象的内存都在堆中分配,其大小可
- Elasticsearch 通常如何工作?我们将文档索引到 Elasticsearch 中并对其运行查询以获得满足提供的搜索条件的文档。 我