java类初始块2023024
迪丽瓦拉
2024-05-14 22:54:21
0

新篇章:初始化块
初始化块是Java类里可出现的第4种成员(前面依次有成员变量、方法和构造器),一个类里可以有多个初始化块,相同类型的初始化块之间有顺序:前面定义的初始化块先执行,后面定义的初始化块后执行。
初始化块的修饰符只能是static,要不就是没有修饰符,使用static修饰的初始化块被称为类初始化块(静态初始化块),没有static修饰的初始化块被称为实例初始化块(非静态初始化块)。初始化块里的代码可以包含任何可执行性语句,包括定义局部变量、调用其他对象的方法,以及使用分支、循环语句等。
当创建Java对象时,系统总是先调用该类里定义的实例初始化块,如果一个类里定义了2个实例初始化块,则前面定义的实例初始化块先执行,后面定义的实例初始化块后执行。
初始化块虽然也是Java类的一种成员,但它没有名字,也就没有标识,因此无法通过类、对象来调用初始化块。实例初始化块只在创建Java对象时隐式执行,而且在构造器执行之前自动执行。类初始化则在类初始化阶段自动执行。
实例初始化块、声明实例变量指定的默认值都可认为是对象的初始化代码,它们的执行顺序与源程序中的排列顺序相同。
加上构造器执行顺序呢?
其初始化顺序是:先执行实例初始化块或声明实例变量时指定的初始值(这两个地方指定初始值的执行顺序与它们在源代码中的排列顺序相同),再执行构造器里指定的初始值。
从某种程度上来看,实例初始化块是构造器的补充,实例初始化块总是在构造器执行之前执行。系统同样可使用实例初始化块来进行对象的初始化操作。
与构造器不同的是,实例初始化块是一段固定执行的代码,它不能接收任何参数。因此实例初始化块对同一个类的所有对象所进行的初始化处理完全相同。基于这个原因,不难发现实例初始化块的基本用法,如果有一段初始化处理代码对所有对象完全相同,且无须接收任何参数,就可以把这段初始化处理代码提取到实例初始化块中。
注意:
实际上实例初始化块是一个假象,使用javac命令编译Java类 后,该Java类中的实例初始化块会消失—实例初始化块中代码会被“还原”到每个构造器中,且位于构造器所有代码的最前面。与构造器类似,创建一个Java对象时,不仅会执行该类的实例初始化块和构造器,而且系统会一直上溯到java.lang.Object类,先执行java.lang.Object类的实例初始化块,开始执行java.lang.Object的构造器,依次向下执行其父类的实例初始化块,开始执行其父类的 构造器……最后才执行该类的实例初始化块和构造器,返回该类的对象。
除此之外,如果希望类加载后对整个类进行某些初始化操作,例如当Person类加载后,就需要把Person类的eyeNumber类变量初始化为 2,此时需要使用static关键字来修饰初始化块,使用static修饰的初始化块被称为类初始化块(静态初始化块)。
类初始化块
如果定义初始化块时使用了static修饰符,则这个初始化块就变成了类初始化块,也被称为静态初始化块(实例初始化块负责对对象执行初始化,类初始化块则负责对类进行初始化)。类初始化块是类相关的,系统将在类初始化阶段执行类初始化块,而不是在创建对象时才执行。因此类初始化块总是比实例初始化块先执行。用于对整个类进行初始化处理,通常用于对类变量执行初始化处理。类初始化块不能对实例变量进行初始化处理。
注意:
静态初始化块也被称为类初始化块,也属于类的静态成员,同样需要遵循静态成员不能访问非静态成员的规则,因此类初始化块不能访问非静态成员,包括不能访问实例变量和实例方法。与实例初始化块类似的是,系统在类初始化阶段执行类初始化块时 ,不仅会执行本类的类初始块,还会一直上溯到java.lang.Object 类 ( 如果他包含类初始块 ),先 执 行
java.lang.Object类的类初始化块(如果有),然后执行其父类的类初始化块……最后才执行该类的类初始化块,经过这个过程,才完成了该类的初始化过程。只有当类初始化完成后,才可以在系统中使用这个类,包括访问这个类的类方法、类变量或者用这个类来创建实例。
Java系统加载并初始化某个类时,总是保证该类的所有父类 (包括直接父类和间接父类)全部加载并初始化。

当JVM第一次主动使用某个类时,系统会在类准备阶段为该类的所有类变量分配内存,在初始化阶段则负责初始化这些类变量,初始化类变量就是执行类初始化块代码和声明类成员变量时指定的初始值,它们的执行顺序与源代码中的排列顺序相同。

相关内容