Java教程-详解Java 实例初始化
实例初始化块(Instance Initializer block)用于初始化实例数据成员。它在每次创建类的对象时都会执行。
尽管我们可以直接在实例数据成员中进行赋值,但实例初始化块的存在有以下几个用途:
- 执行额外的操作:实例初始化块可以用于执行一些额外的操作,例如计算、加载数据等。这样,我们可以在初始化实例数据成员之前进行一些必要的操作。
- 统一的初始化逻辑:如果有多个构造函数,并且它们都需要执行相同的初始化逻辑,那么实例初始化块可以提供一种统一的初始化方式。通过在实例初始化块中编写共享的初始化代码,可以避免在多个构造函数中重复编写相同的代码。
Que)当我们可以直接在实例数据成员中赋值时,实例初始化块的用途是什么?例如:
class Bike{
int speed=100;
}
为什么要使用实例初始化块?
实例初始化块在初始化实例数据成员时提供了一种灵活的方式,可以执行额外的操作或处理复杂的初始化逻辑。
实例初始化块的示例
让我们看一下执行初始化的实例初始化程序块的简单示例。
class Bike7{
int speed;
Bike7(){System.out.println("速度是"+speed);}
{speed=100;}
public static void main(String args[]){
Bike7 b1=new Bike7();
Bike7 b2=new Bike7();
}
}
输出:
速度是100
速度是100
java中可以在三个地方进行操作:方法constructor堵塞
首先调用什么,实例初始化块或构造函数?
class Bike8{
int speed;
Bike8(){System.out.println("构造函数被调用");}
{System.out.println("实例初始化块被调用");}
public static void main(String args[]){
Bike8 b1=new Bike8();
Bike8 b2=new Bike8();
}
}
输出:
实例初始化块被调用
构造函数被调用
构造函数被调用
在上述示例中,实际上没有首先调用实例初始化块,尽管看起来是这样的。实例初始化块是在创建对象时被调用。在Java编译器中,实例初始化块的代码会被复制到每个构造函数中,放在super()
构造函数调用之后。下图可以帮助我们更好地理解这一点:
请注意,Java编译器会按照实例初始化块出现的顺序复制代码到每个构造函数中。
实例初始化块的规则:
实例初始化块遵循以下三个规则:
- 实例初始化块在创建类的实例时执行。
- 实例初始化块在调用父类构造函数之后执行(即在
super()
构造函数调用之后执行)。 - 实例初始化块按照它们在代码中出现的顺序执行。
在 super() 之后调用的实例初始化程序块的程序
class A{
A(){
System.out.println("调用父类构造函数");
}
}
class B2 extends A{
B2(){
super();
System.out.println("调用子类构造函数");
}
{System.out.println("实例初始化块被调用");}
public static void main(String args[]){
B2 b=new B2();
}
}
输出:
调用父类构造函数
实例初始化块被调用
调用子类构造函数
实例块的另一个例子
class A{
A(){
System.out.println("调用父类构造函数");
}
}
class B3 extends A{
B3(){
super();
System.out.println("调用子类构造函数");
}
B3(int a){
super();
System.out.println("调用子类构造器"+a);
}
{System.out.println("实例初始化块被调用");}
public static void main(String args[]){
B3 b1=new B3();
B3 b2=new B3(10);
}
}
输出:
父类构造函数被调用
实例初始化块被调用
子类构造函数被调用
父类构造函数被调用
实例初始化块被调用
调用子类构造函数 10