Java类初始化顺序详解

 更新时间:2023年08月14日 09:11:25   作者:不打魔兽的少年  
这篇文章主要介绍了Java类初始化顺序详解,java语言在使用过程中最先开始就是初始化,在工作中如果遇到什么问题需 要定位往往到最后也可能是初始化的问题,因此掌握初始化的顺序很重要,需要的朋友可以参考下

Java 类初始化介绍

java语言在使用过程中最先开始就是初始化,在工作中如果遇到什么问题需 要定位往往到最后也可能是初始化的问题,因此掌握初始化的顺序很重要。

根据java 语言特性,本人针对初始化中常遇到的一些关键点做了总结,当然是基于代码之上的,主要针对JVM加载一个类之后,类的属性等在内存中的初始化,主要静态的变量和非静态的变量,以及静态代码块,普通代码块等。具体参考下面的图:

这里写图片描述

简单介绍下图的意思,java类对象初始化主要包括:

  • 静态基本变量;
  • 静态类变量;
  • 静态代码块;
  • 普通基本变量;
  • 普通类类型变量;
  • 普通代码块;
  • 构造方法;

初始化的时候主要就是这些属性,但是该类继承自父类,则初始化顺序号包括基类的这些属性,即初始化属性包括本类的这些属性+父类的这些属性,并且基类的属性和本类的属性交叉初始化。

无继承关系初始化

首先查看基本代码

首先看TestB.java类

private  static String tag = "TestB";
//静态变量
private static int  staticVarA = initVar("staticVarA");
//静态代码块
static{
    initVar("static init block ");
}
//普通变量
private  int normalA = initVar("normalA");
// 普通代码块
{
    initVar("normal init block");
}
public TestB(){
    System.out.println(initVar("constructor"));
}
static int initVar(String str){
    System.out.println(tag +" "+str);
    return 2018;
}

其次是 JavaInitWithMain.java 类

private  static String tag = "JavaInitWithMain";
//静态变量
private static int  staticVarA = initVar("staticVarA");
//静态代码块
static{
    initVar("static init block ");
}
//普通变量
private  int normalA = initVar("normalA");
// 普通代码块
{
    initVar("normal init block");
}
private static TestB nB = new TestB();
private TestB nb2 = new TestB();
public JavaInitWithMain(){
    System.out.println(initVar("constructor"));
}
static int initVar(String str){
    System.out.println(tag +" "+str);
    return 2020;
}
public static void main(String[] args) {
    System.out.println("-------main method-------");
    System.out.println("do nothing");
}

接下来是运行结果:

这里写图片描述

结果分析:

代码很简单,分别在2个类中的基本属性,在JavaInitWithMain 类中的main方法中不做任何操作,查看结果。

根据结果可知,JVM加载了JavaInitWithMain类之后初始化了该类的属性,顺序是 静态的—>非静态的—->构造方法,静态的包括静态的基本变量,静态的类类型变量,静态代码块,这三个的顺序是 程序员的书写顺序。

得出结论:无继承关系时的初始化顺序 静态属性(静态基本变量,静态类类型变量,静态代码块)—>非静态的属性(基本类型变量,基本类类型变量,基本代码块)—>构造方法

存在继承关系的初始化

类基本不变,增加TestB的子类TheSonofTestB,如下

public class TheSonofTestB extends TestB {
private  static String tag = "TheSonofTestB";
//静态变量
private static int  staticVarA = initVar("staticVarA");
//静态代码块
static{
    initVar("static init block ");
}
//普通变量
private  int normalA = initVar("normalA");
// 普通代码块
{
    initVar("normal init block");
}
public TheSonofTestB(){
    System.out.println(initVar("constructor"));
}
static int initVar(String str){
    System.out.println(tag +" "+str);
    return 2019;
}
}

JavaInitWithMain中增加静态的属性,同时为了方便查看去掉了改类中的静态类变量和静态类类型变量,如下: private static TheSonofTestB sonNB = new TheSonofTestB();

查看 输出结果,如下:

同样分析下结果: 初始化sonNB 时先去初始化其基类的静态属性,然后初始化TheSonofTestB的静态属性,接下来是父类的基本变量,父类的构造,子类的基本变量,最后子类自己的构造。

得出结论: 不管是本类存在继承还是本类的类对象属性存在继承

在初始化时都是: 父类的静态属性—->子类的静态属性—->父类的基本类型属性—->父类的构造—>子类的基本属性—->子类的构造

这里写图片描述

写在最后

最后我想说2点:

1:不管存在不存在继承,静态的属性—>非静态的属性—->构造方法 都是初始化的顺序,存在继承时,依然一样,只不过父类和子类的这些属性交替进行

2:思考问题: 子类如果覆盖了父类的静态属性,那么调用子类的静态属性时,静态属性的值应该是什么?子类是静态属性共有几个?各位可自行试验

到此这篇关于Java类初始化顺序详解的文章就介绍到这了,更多相关Java类初始化内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java中toString函数的使用示例代码

    Java中toString函数的使用示例代码

    toString()函数用于将当前对象以字符串的形式返回,比如我定义了一个User类,创建了一个user对象,然后使用相应命令去打印user对象,本文结合示例代码介绍了toString函数的使用,需要的朋友可以参考下
    2024-02-02
  • Java 深入浅出掌握Map集合之双列集合

    Java 深入浅出掌握Map集合之双列集合

    双列集合是每个元素都有键与值两部分组成的集合,记录的是键值对对应关系,即通过键可以找到值,键必须是唯一,值可以重复,接下来跟着小编具体了解吧
    2021-11-11
  • 详解Spring Cloud Gateway 数据库存储路由信息的扩展方案

    详解Spring Cloud Gateway 数据库存储路由信息的扩展方案

    这篇文章主要介绍了详解Spring Cloud Gateway 数据库存储路由信息的扩展方案,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • myBatis的mapper映射文件之批量处理方式

    myBatis的mapper映射文件之批量处理方式

    这篇文章主要介绍了myBatis的mapper映射文件之批量处理方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-09-09
  • Druid简单实现数据库的增删改查方式

    Druid简单实现数据库的增删改查方式

    这篇文章主要介绍了Druid简单实现数据库的增删改查方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • 教你使用java实现去除各种空格

    教你使用java实现去除各种空格

    本文给大家汇总介绍了5种java中去除空格的方法,分别是String.trim()、str.replace(" ", "");、replaceAll(" +","");以及自定义的remove函数,非常的简单实用,需要的小伙伴可以参考下。
    2015-03-03
  • 在springboot中如何使用filter设置要排除的URL

    在springboot中如何使用filter设置要排除的URL

    这篇文章主要介绍了在springboot中如何使用filter设置要排除的URL,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • Java中IO流 字节流实例详解

    Java中IO流 字节流实例详解

    这篇文章主要介绍了Java中IO流 字节流实例详解的相关资料,需要的朋友可以参考下
    2017-05-05
  • Java Fluent Mybatis实战之构建项目与代码生成篇上

    Java Fluent Mybatis实战之构建项目与代码生成篇上

    Java中常用的ORM框架主要是mybatis, hibernate, JPA等框架。国内又以Mybatis用的多,基于mybatis上的增强框架,又有mybatis plus和TK mybatis等。今天我们介绍一个新的mybatis增强框架 fluent mybatis
    2021-10-10
  • Java基于Google zxing生成带logo的二维码图片

    Java基于Google zxing生成带logo的二维码图片

    zxing是一个开放源码的,用java实现的多种格式的1D/2D条码图像处理库,本文主要介绍了Java基于Google zxing生成带logo的二维码图片,具有一定的参考价值,感兴趣的可以了解一下
    2023-10-10

最新评论