当前位置: 首页 > 编程笔记 >

Java初始化块及执行过程解析

秦育
2023-03-14
本文向大家介绍Java初始化块及执行过程解析,包括了Java初始化块及执行过程解析的使用技巧和注意事项,需要的朋友参考一下

问题:Java对象初始化方式主要有哪几种?分别是什么?

针对上面的问题,想必大家脑海中首先浮现出的答案是构造器,没错,构造器是Java中常用的对象初始化方式。

还有一种与构造器作用非常相似的是初始化块,它可以对Java对象进行初始化操作。下面主要阐述Java的初始化块及执行过程

Java初始化块其实是Java类的成员之一,其语法格式如下:

[修饰符]{

  //初始化块的可执行代码

  ...

}

初始化块的修饰符只能是static,使用static修饰符的初始化块称为静态初始化块,后面会介绍到。

下面通过一段程序代码看看创建对象Dog时发生了什么。

public class Dog {
  //定义一个初始化块
  {
    System.out.println("第一个初始化块");
  }
  //定义第二个初始化块
  {
    System.out.println("第二个初始化块");
  }
  //定义无参的构造器
  public Dog() {
    System.out.println("Dog的无参构造器");
  }  
  public static void main(String[] args) {    
    new Dog();
  }
}

运行结果为:

第一个初始化块
第二个初始化块
Dog的无参构造器

从运行结果可以看出:当创建一个Dog对象时,程序先执行初始化块后执行构造器,而且两个初始化的执行顺序是按照前后顺序执行的。

由于初始化块只在创建Java对象时隐士的执行(所有的初始化块全部执行),为了让程序更加的简洁和可读性更强,一般一个类里最多只有一个初始化块。

既然初始化块和构造器都是创建对象的时候执行,那么它们有什么区别呢?

从某种程度上来看,初始化块是构造器的补充,与构造器不同的是,初始化块是一段固定执行的代码,不能接收任何的参数,而构造器是可以接收参数的。如果程序中有两个构造器,并且它们有公共的无需接收参数的代码,则可以把这些相同的公共代码放到初始化块中,提高代码的可维护性。

当普通初始化块被static修饰时,则这个初始化块就是静态初始化块,也被称为类初始化块。

普通初始化块负责对对象进行初始化,而静态初始化块负责对类进行初始化,所以静态初始化块总是比普通初始化块先执行。

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

静态初始化块也是类的静态成员,仍然需要遵循静态成员不能访问非静态成员的规则,包括不能访问实例变量和实例方法

初始化块执行的时候会一直上溯到java.lang.Object类,先执行Object的初始化块,再执行其父类的初始化块...最后才执行该类自己的初始化块。

下面看下这段代码的执行顺序结果:

class Biology{
  static {
    System.out.println("Biology的静态初始化块");
  }
  {
    System.out.println("Biology的普通初始化块");
  }
  public Biology(){
    System.out.println("Biology的无参构造器");
  }
}
class Animal extends Biology{
  static {
    System.out.println("Animal的静态初始化块");
  }
  {
    System.out.println("Animal的普通初始化块");
  }
  public Animal(){
    System.out.println("Animal的无参构造器");
  }
  public Animal(String name){
    this();//调用同类中的重载构造器
    System.out.println("Animal的带参构造器,name="+name);
  }
}
class Cat extends Animal{
  static {
    System.out.println("Cat的静态初始化块");
  }
  {
    System.out.println("Cat的普通初始化块");
  }
  public Cat(){
    //调用父类中带参数的构造器
    super("Java典籍");
    System.out.println("Cat的无参构造器");
  }
}
public class Test {
  public static void main(String[] args) {
    new Cat();
    System.out.println("=========");
    new Cat();
  }
}

执行结果如下:

Biology的静态初始化块
Animal的静态初始化块
Cat的静态初始化块
Biology的普通初始化块
Biology的无参构造器
Animal的普通初始化块
Animal的无参构造器
Animal的带参构造器,name=Java典籍
Cat的普通初始化块
Cat的无参构造器
=========
Biology的普通初始化块
Biology的无参构造器
Animal的普通初始化块
Animal的无参构造器
Animal的带参构造器,name=Java典籍
Cat的普通初始化块
Cat的无参构造器

从上面的执行结果来看,第一次创建Cat对象时,由于html" target="_blank">系统还未有Cat对象,因此需要先加载并初始化Cat类,初始化Cat类会先执行其顶层父类的静态初始化块,再执行其直接父类的静态初始化块,最后才执行其本身的静态初始化块。

一旦Cat类初始化成功后,其在虚拟机中一直存在,当第二次再创建Cat对象时 无需再对Cat类进行初始化。

综上,一个类初始化的执行顺序为:父类静态初始化块,该类静态初始化块,父类普通初始化块,父类构造器,该类普通初始化块,该类构造器。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 问题内容: 正如某些消息来源所说,Java实例初始化块在创建实例时或在构造函数之前立即执行。但是想象一下这种情况: 输出是(如预期的那样): 所以我的问题是-实例初始化块的正确定义是什么,因为它显然没有在构造函数之前执行,因为输出应该是 因为Main()构造函数是在调用super()之前调用的,所以Main初始化块应该是第一个。 问题答案: 不会。初始化块直接复制到构造函数中。显然那里也有一个隐式

  • 本文向大家介绍Java中初始化块详解及实例代码,包括了Java中初始化块详解及实例代码的使用技巧和注意事项,需要的朋友参考一下 Java中初始化块详解 在Java中,有两种初始化块:静态初始化块和非静态初始化块. 静态初始化块:使用static定义,当类装载到系统时执行一次.若在静态初始化块中想初始化变量,那仅能初始化类变量,即static修饰的数据成员. 非静态初始化块:在每个对象生成时都会被执

  • 问题内容: 据我了解,“静态初始化块”用于设置静态字段的值(如果无法在一行中完成的话)。 但是我不明白为什么我们需要为此设置一个特殊的块。例如,我们将字段声明为静态(无值分配)。然后编写几行代码,生成并为上面声明的静态字段分配一个值。 为什么我们需要在这样一个特殊的块这样的行:? 问题答案: 在非静态块: 每次构造类的实例时被调用。在静态块只被调用一次,当类本身初始化,无论该类型的有多少对象创建。

  • 问题内容: 在运行时,我经常创建/修改 log4j Logger,Appenders,Levels,Layouts,并且有时需要将所有内容重置为默认值。 Log4j 系统具有定义明确的 默认初始化过程 ,该 过程 在将 log4j 类加载到内存时执行。有什么方法可以稍后在运行时以编程方式重新执行整个过程吗? 我在 log4j 文档中找到了几种方法,但是不确定它们中的任何一种是否可以执行 默认初始化

  • 问题内容: 我们可以将代码放入构造函数或方法或初始化块中。初始化块有什么用?每个Java程序都必须有它吗? 问题答案: 首先,有两种类型的初始化块: 实例初始化块,以及 静态初始化块。 此代码应说明它们的用法以及执行顺序: 印刷品: 如果要运行某些代码而不管使用哪个构造函数,或者想要对匿名类进行一些实例初始化,则实例迭代块很有用。

  • 本文向大家介绍详解SpringBoot程序启动时执行初始化代码,包括了详解SpringBoot程序启动时执行初始化代码的使用技巧和注意事项,需要的朋友参考一下 因项目集成了Redis缓存部分数据,需要在程序启动时将数据加载到Redis中,即初始化数据到Redis。 在SpringBoot项目下,即在容器初始化完毕后执行我们自己的初始化代码。 第一步:创建实现ApplicationListener接