Java程序的初始化顺序,static{}静态代码块和实例语句块的使用方式

 更新时间:2024年01月30日 14:20:06   作者:pan_junbiao  
这篇文章主要介绍了Java程序的初始化顺序,static{}静态代码块和实例语句块的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

1、Java程序的初始化顺序

在 Java 语言中,当实例对象时,对象所在类的所有成员变量首先要进行初始化,只有当所有类成员完成初始化后,才会调用对象所在的构造函数创建对象。

Java 程序的初始化一般遵循以下三个原则:

  • 静态对象(变量)、非静态对象(变量)。
  • 父类优先于子类进行初始化。
  • 按照成员变量定义顺序进行初始化。

Java 程序的初始化工作可以在许多不同的代码块中来完成,

例如:静态代码块、实例语句块、构造函数等。

1.1 普通类的执行顺序

普通类的执行顺序为:静态代码块 → 实例语句块 → 构造函数。

【示例】普通类的执行顺序。

(1)创建普通类

/**
 * 普通类
 * @author pan_junbiao
 **/
public class MyClass
{
    //静态代码块
    static
    {
        System.out.println("静态代码块");
    }
 
    //实例语句块
    {
        System.out.println("实例语句块");
    }
 
    //构造函数
    public MyClass()
    {
        System.out.println("构造函数");
    }
}

(2)执行方法

/**
 * Java普通类的执行顺序
 * @author pan_junbiao
 */
public static void main(String[] args)
{
    //创建普通类对象
    MyClass myClass = new MyClass();
}

执行结果:

1.2 继承类的执行顺序

继承类的执行顺序为:父类静态代码块 → 子类静态代码块 → 父类实例语句块 → 父类构造函数 → 子类实例语句块 → 子类构造函数。

【示例】继承类的执行顺序。

(1)创建父类

/**
 * 父类
 * @author pan_junbiao
 **/
public class Parent
{
    //静态代码块
    static
    {
        System.out.println("父类静态代码块");
    }
 
    //实例语句块
    {
        System.out.println("父类实例语句块");
    }
 
    //构造函数
    public Parent()
    {
        System.out.println("父类构造函数");
    }
}

(2)创建子类

/**
 * 子类
 * @author pan_junbiao
 **/
public class Child extends Parent
{
    //静态代码块
    static
    {
        System.out.println("子类静态代码块");
    }
 
    //实例语句块
    {
        System.out.println("子类实例语句块");
    }
 
    //构造函数
    public Child()
    {
        System.out.println("子类构造函数");
    }
}

(3)执行方法

/**
 * Java继承类的执行顺序
 * @author pan_junbiao
 */
public static void main(String[] args)
{
    //创建子类对象
    Child child = new Child();
}

执行结果:

1.3 成员变量初始化的优先级

这里需要注意的是,(静态)非静态成员域在定义时初始化和(静态)非静态块中初始化的优先级是平级的,也就是说按照从上到下初始化,最后一次初始化为最终的值(不包括非静态的成员域在构造器中初始化)。

所以在(静态)非静态块中初始化的域甚至能在该域声明的上方,因为分配存储空间在初始化之前就完成了。

【示例】(静态)非静态块中成员变量初始化的优先级。

/**
 * (静态)非静态块中成员变量初始化的优先级
 * @author pan_junbiao
 **/
public class TestStatic
{
    static { a = 2;}
    static int a = 1;
    static int b = 3;
    static { b = 4; }
 
    public static void main(String[] args)
    {
        System.out.println("初始化后的变量的值:");
        System.out.println(a);
        System.out.println(b);
    }
}

执行结果:

2、static{}静态代码块的使用

static{} 静态代码块在类的加载时执行,并且只执行一次,且在 main 方法之前执行。一个类中可以有多个静态代码块,执行顺序自上而下。一个静态代码块只能访问该静态代码块之前的静态变量。

static{} 静态代码块在类初次被加载的时候执行且仅会被执行一次,所以可以起到优化程序性能的作用。

static{} 静态代码块的语法:

//静态代码块
static
{
    //Java程序
}

3、实例语句块的使用

除了static{} 静态代码块之外,还有一种语句块叫做:实例语句块。

顾名思义,就是在实例化对象时执行,并不是在类加载时执行。

实例语句块的具体执行时间是在实例化对象时的构造函数之前执行的。

实例语句块的语法:

//实例语句块
{
    //Java程序
}

4、练习题目

最后来一道题目练习一下关于 static{} 静态代码块、实例语句块和构造函数的执行顺序。

例题如下:

/**
 * 判断以下程序的执行顺序
 * @author pan_junbiao
 **/
public class CodeOrder
{
    //静态代码块
    static
    {
        System.out.println("A");
    }
 
    //程序入口
    public static void main(String[] args)
    {
        System.out.println("Y");
        new CodeOrder();
        System.out.println("Z");
    }
 
    //构造函数
    public CodeOrder()
    {
        System.out.println("B");
    }
 
    //实例语句块
    {
        System.out.println("C");
    }
 
    //静态代码块
    static
    {
        System.out.println("X");
    }
}

执行结果:

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • spring如何快速稳定解决循环依赖问题

    spring如何快速稳定解决循环依赖问题

    这篇文章主要介绍了spring如何快速稳定解决循环依赖问题,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-03-03
  • springboot vue 跨域问题的解决

    springboot vue 跨域问题的解决

    这篇文章主要介绍了springboot vue 跨域问题的解决,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-10-10
  • ruoyi-springboot框架新增模块调接口报404的解决方案

    ruoyi-springboot框架新增模块调接口报404的解决方案

    这篇文章主要介绍了ruoyi-springboot框架新增模块调接口报404的解决方案,文中通过代码示例给大家讲解的非常详细,对大家的学习或工作有一定的帮助,需要的朋友可以参考下
    2024-03-03
  • java 中ThreadLocal本地线程和同步机制的比较

    java 中ThreadLocal本地线程和同步机制的比较

    这篇文章主要介绍了java 中ThreadLocal本地线程和同步机制的比较的相关资料,需要的朋友可以参考下
    2017-03-03
  • 使用Feign扩展包实现微服务间文件上传

    使用Feign扩展包实现微服务间文件上传

    这篇文章主要为大家详细介绍了使用Feign扩展包实现微服务间文件上传,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-04-04
  • java生成申请单序列号的实现方法

    java生成申请单序列号的实现方法

    申请单序列号一般要求根据一定的规则生成后几位连续的字符串,下面是我项目中使用的生成序列号的代码,其中用到了锁机制,有需要的朋友可以参考一下
    2014-01-01
  • Java if(boolean)和if(boolean=true)区别解析

    Java if(boolean)和if(boolean=true)区别解析

    这篇文章主要介绍了Java if(boolean)和if(boolean=true)区别解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
    2020-02-02
  • 深入理解Java中的EnumMap和EnumSet

    深入理解Java中的EnumMap和EnumSet

    这篇文章主要介绍了深入理解Java中的EnumMap和EnumSet,一般来说我们会选择使用HashMap来存储key-value格式的数据,考虑这样的特殊情况,一个HashMap的key都来自于一个Enum类,这样的情况则可以考虑使用本文要讲的EnumMap,需要的朋友可以参考下
    2023-11-11
  • Java中如何避免sql注入实例详解

    Java中如何避免sql注入实例详解

    SQL注入是最常见的攻击方式之一,它不是利用操作系统或其它系统的漏洞来实现攻击的,而是程序员因为没有做好判断,被不法用户钻了SQL的空子,下面这篇文章主要给大家介绍了关于Java中如何避免sql注入的相关资料,需要的朋友可以参考下
    2022-01-01
  • Java数组实例练习题整理

    Java数组实例练习题整理

    在本篇文章中小编给各位分享的是关于Java数组实例练习题以及相关代码整理,有需要的朋友们跟着学习下。
    2019-07-07

最新评论