1.什么是初始化块
初始化块是java类的一个成员,与 属性,方法,构造器属于平等地位。
它的主要作用是 初始化 类属性 和 对象属性。
初始化块 是 用花括号 括起来的一段代码块。
2.初始化块的特点
1.初始化块有两种 : 普通初始化块 和 静态初始化块。
2.静态初始化块 是用 static 来修饰的。
3.一个类中可以有多个初始化块。
4.初始化块都是被隐式调用的。
5.静态初始化块 : 类加载到系统时执行一次。仅能初始化类变量。
6.普通初始化块 :在每个对象创建时都会执行一次,且会在构造方法执行之前执行。
7.相同类型的初始化块的执行顺序是 : 谁先定义的,谁先执行。
8.不同类型的初始化块的执行顺序是 : 先执行 静态初始化块,后执行普通初始化块。
3.写个例子体会一下初始化块的特点
public class InitBlockA {
private String name; // 普通属性
private static String nickName; // 类属性
// 普通初始化块1
{
System.out.println("This is common init block 1");
this.name = "name01";
this.nickName = "nickName01";
}
// 普通初始化块2
{
System.out.println("This is common init block 2");
this.name = "name02";
this.nickName = "nickName02";
}
// 静态初始化块1
static {
System.out.println("This is static init block 1");
//this.name = "staticName01"; 只能初始化 类属性(静态属性)
nickName = "staticNickName01";
}
// 静态初始化块 2
static {
System.out.println("This is static init block 2");
nickName = "staticNickName02";
}
// 无参构造
public InitBlockA() {
System.out.println("This is Constructor without params");
}
// 构造器
public InitBlockA(String name) {
System.out.println("This is Constructor with a param : name");
this.name = name;
}
// 下面是常规的 getter/setter方法 和 toString方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static String getNickName() {
return nickName;
}
public static void setNickName(String nickName) {
InitBlockA.nickName = nickName;
}
@Override
public String toString() {
return "InitBlockA{" +
"name='" + name + '\'' +
'}';
}
}
/**
* 测试类 : 直接创建两个对象,观察执行顺序
*/
public class Application {
public static void main(String[] args) {
InitBlockA initBlockA = new InitBlockA();
System.out.println("==================");
InitBlockA initBlockB = new InitBlockA("paramName");
}
}
执行结果如下 :
This is static init block 1
This is static init block 2
This is common init block 1
This is common init block 2
This is Constructor without params
==================
This is common init block 1
This is common init block 2
This is Constructor with a param : name
执行结果分析 :
第一行第二行表示 : 静态初始化块仅在类加载时执行一次,且谁先定义谁先执行。
第三行第四行第五行表示 : 普通初始化块 在 构造方法之前执行 ,且谁先定义谁先执行。
第一行第二行 和 第三行第四行 表示 :
静态初始化块 先于普通初始化块执行,因为是随着类的加载执行的。
初始化块可以写多个。
4.静态初始化块的继承特性
当类存在继承关系时,会从上到下,一级一级的执行静态初始化块。
【这个可能与类加载的双亲委派机制有关,详细的后面再讲】
下面通过一个例子来体会一下:
C 继承 B,B 继承 A
class A{
// 静态初始化块
static {
System.out.println("static init block A");
}
// 普通初始化块
{
System.out.println("common init block A");
}
// 构造方法
public A() {
System.out.println("Constructor without params A");
}
}
class B extends A{
// 静态初始化块
static {
System.out.println("static init block B");
}
// 普通初始化块
{
System.out.println("common init block B");
}
// 构造方法
public B() {
System.out.println("Constructor without params B");
}
}
class C extends B{
// 静态初始化块
static {
System.out.println("static init block C");
}
// 普通初始化块
{
System.out.println("common init block C");
}
// 构造方法
public C() {
System.out.println("Constructor without params C");
}
}
/**
* 测试类 : 创建两个 C 对象,查看初始化块的执行过程
*/
public class InitBlockB {
public static void main(String[] args) {
C c = new C();
System.out.println("=====================");
C c1 = new C();
}
}
执行结果:
static init block A
static init block B
static init block C
common init block A
Constructor without params A
common init block B
Constructor without params B
common init block C
Constructor without params C
=====================
common init block A
Constructor without params A
common init block B
Constructor without params B
common init block C
Constructor without params C
5.完成
Congratulations!
You are one step closer to success!