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 初始化块详解的主要内容,如果未能解决你的问题,请参考以下文章

Java面向对象 类的成员之代码块的详解

java中的静态变量,静态方法与静态代码块详解

java static块详解

java中静态代码块的用法—— static用法详解

java中静态代码块的用法 static用法详解

java中静态代码块的用法 static用法详解和static静态导入