Java 初始化块详解
Posted 流楚丶格念
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java 初始化块详解相关的知识,希望对你有一定的参考价值。
文章目录
代码案例摘自:https://blog.csdn.net/a647777/article/details/108789049
概念摘自百度百科
初始化块概念
初始化块用于初始化类的对象。分为实例初始化块和静态初始化块。其中在一个对象编译的过程中,静态初始化块只在类加载的时候被初始化一次,并且是初始化内容存在堆的方法区(元空间)中,而实例化代码块,则是在对象被实例化的时候调用。
初始化块是类的第4种成员(成员变量、方法、构造器),与构造器作用有些类似,用于对JAVA对象进行初始化操作。
初始化块定义
实例化代码块:
Java语句;
使用static关键字来定义“静态代码块”
static
Java语句;
初始化块举例
例如:
public class Animal
//定义初始化块
int a = 6;
if(a>4)
System.out.println("Animal初始化块,局部变量a的值大于4");
System.out.println("Animla的初始化块");
//再定义一个初始化块
System.out.println("Animal的第二个初始化块");
//定义构造器
public Animal()
System.out.println("Animal的无参构造器");
public class Demo01
public static void main(String[] args)
Animal a = new Animal();
运行结果如下:
可见,JAVA创建对象时,首先执行初始化块。
如果一个类中定义了多个初始化块,则按照顺序执行(这其实没有什么意义,因为初始化块都可以合并为一个)。并且,初始化块在构造器(构造函数)之前执行。
初始化块与构造器区别
二者的区别是:
- 初始化块是一段固定的代码,它无法接受任何参数,对一个类的所有对象进行的初始化处理完全相同;
- 而构造器则是可以带参数的,对不同的对象,参数不同,可以进行不同的初始化处理。
静态初始化块
与静态方法、静态成员变量类似,在初始化块之前加上static就变成了静态初始化块。
普通初始化块是对象的,负责初始化具体对象;
静态初始化块是类的,负责初始化类。
与静态方法相同,静态初始化块不能访问非静态方法,非静态成员变量(因为静态初始化块是在类加载的时候就执行了的,这个时候可能还没有类的对象,就没办法执行非静态方法、非静态成员变量)
初始化块执行顺序
JAVA中,创建一个对象时,若是第一次创建该类的对象,则会首先加载并初始化该类,因此会首先执行其所有父类的静态初始化块(按照顺序执行,首先是最顶层父类,然后是下一层,层层向下执行),最后是其本身的静态初始化块。
再依次执行所有父类的初始化块、构造器,最后是自己类的初始化块、构造器。
一旦该对象创建成功,该类在虚拟机中将一直存在,第二次创建该类的对象时,就无需加载与初始化类。
其中,类的静态初始化块、静态成员变量的声明都可以看作是类的初始化代码,执行顺序依代码顺序而定。
代码举例如下:
class Person
static
System.out.println("我是Person类的静态初始化块");
System.out.println("我是Person类的普通初始化块");
public Person()
System.out.println("我是Person类的无参构造器");
class Police extends Person
static
System.out.println("我是Police类的静态初始化块");
System.out.println("我是Police类的普通初始化块");
public Police()
System.out.println("我是Police类的无参构造器");
public Police(int a)
//调用自己的无参构造器
this();
System.out.println("我是Police类的有参构造器,参数为:"+a);
class SWAT extends Police
static
System.out.println("我是SWAT的静态初始化块");
System.out.println("我是SWAT的普通初始化块");
public SWAT()
//调用直接父类的有参构造器
super(10);
System.out.println("我是SWAT的无参构造器");
public class Demo01
public static void main(String[] args)
new SWAT();
上述代码创建了三个类,Person,Police,SWAT。其中,Person是Police的直接父类,Police是SWAT的直接父类。
输出结果为:
我是Person类的静态初始化块
我是Police类的静态初始化块
我是SWAT的静态初始化块
我是Person类的普通初始化块
我是Person类的无参构造器
我是Police类的普通初始化块
我是Police类的无参构造器
我是Police类的有参构造器,参数为:10
我是SWAT的普通初始化块
我是SWAT的无参构造器
因为这是第一次使用SWAT这个类,因此需要初始化类,因此会首先依次执行Person类的静态初始化块、Police类的静态初始化块和SWAT类的静态初始化块。
随后,创建对象时,则会依次执行各个父类的初始化块,构造器。首先是Person类的普通初始化块、无参构造器,然后是Police类的普通初始化块、无参构造器、有参构造器(因为SWAT的无参构造器中调用了Police的有参构造器(super(10)),而Police的有参构造器中调用了Police的无参构造器(this())),最后是SWAT自己的普通初始化块、无参构造器。
修改一下代码
public class Demo01
public static void main(String[] args)
new SWAT();
new SWAT();
输出将增加:
我是Person类的普通初始化块
我是Person类的无参构造器
我是Police类的普通初始化块
我是Police类的无参构造器
我是Police类的有参构造器,参数为:10
我是SWAT的普通初始化块
我是SWAT的无参构造器
因为该类已经被加载过了,因此,各个类的静态初始化块均不会被重新运行。
以上是关于Java 初始化块详解的主要内容,如果未能解决你的问题,请参考以下文章