代码块

一、基本介绍

​ a) 代码块又称为==初始化快==,属于类中的成员(即 是类的一部分),类似于方法,讲逻辑语句封装在方法体重,通过 {} 包裹起来。
但和方法不一样,其没有方法名,没有返回值,没有参数,只有方法体,而且不用通过对象或类显示调用,而是==加载类==时,或在创建对象时隐式调用

​ b)能干嘛:

  1. 相当于另一种形式的构造器(对构造器的补充),可以加入初始化的代码。
    场景:多个构造器中都有重复的语句,可以将其抽取出来,放到 ==代码块==中,提高代码的复用性

二、基本语法

1
2
3
4
[修饰符]{

方法体
};

注意:
1)修饰符 可选,只能写static
2)代码块分为两类,使用 static 修饰的称为静态代码块,没有static 修饰的,称为 普通代码块/非静态代码块。
3)逻辑语句可以为任何语句 (输入、输出、方法调用、循环、判断等)
4);号可选

三、代码块的使用注意事项

  1. static 代码块也叫 ==静态代码块==,它随 ==类的加载==而执行,并且==只会执行一次==,如果是普通代码块(即没有 static 修饰),则每创建一个对象,就会执行一次。

  2. 类什么时候被加载

    1. 创建对象实例时(即 使用 new )

    2. 创建子类对象实例时,父类也会被加载!—->

      1. 首先加载类信息==从父类开始逐级向下==>GrandPa信息–> Father—->son
      2. 在堆中开辟 内存空间 —-> 储存GrandPa—>储存 Father—>储存son

      image-20221103111308639

    3. 使用类的 ==静态成员==(静态属性、静态方法)

  3. 普通代码块:
    在创建对象实例时,会被==隐式的调用==,对象实例被创建一次,就会创建一次。(每一个new的出现,都会有一个普通代码块被拉出来毒打)。但如果是 ==使用类的静态成员==,则它不会干活。

小结:

1. static 代码块是 ==**类加载**==时进行,只会执行一次。
1. 普通代码块是在 创建对象 时调用,有一个对象被创建就调用一次。
1. 类加载的三种情况需要记住

四、案例分析理解 静态代码块、代码块、构造器的执行过程。

  1. 单个类的执行过程分析
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    class signle{
    private static int n1=getN1();
    public static int getN1(){
    System.out.println("静态变量初始化");
    return 100;
    }
    static {
    System.out.println("静态代码块初始化");
    }
    private int n2=getN2();
    public int getN2(){
    System.out.println("普通变量初始化");
    return 200;
    }
    //1.先加载类信息,即初始化静态代码块和静态变量
    public signle() {
    // 默认的super()调用父类
    //调用普通方法块和 初始化普通变量
    //构造器方法
    }
    }

综合案例

创建一个==具有继承关系的类的对象==

  1. 从继承关系开始==加载类的信息==(从父类开始)。
  2. 父类的静态代码和属性初始化(优先级一样,按定义的顺序执行)
  3. 子类的静态代码和属性初始化(优先级一样,按定义的顺序执行)
  4. 父类的普通代码块和普通属性初始化(优先级一样,按定义的顺序执行)
  5. 父类的构造函数
  6. 子类的普通代码块和普通属性初始化(优先级一样,按定义的顺序执行)
  7. 子类的构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
public class CodeBlockDetail04 {
public static void main(String[] args) {
//老师说明
//(1) 进行类的加载
//1.1 先加载 父类 A02 1.2 再加载 B02
//(2) 创建对象
//2.1 从子类的构造器开始
//new B02();//对象
new C02();
}
}
class A02 { //父类
private static int n1 = getVal01();
static {
System.out.println("A02 的一个静态代码块..");//(2)
}
{
System.out.println("A02 的第一个普通代码块..");//(5)
}
public int n3 = getVal02();//普通属性的初始化
public static int getVal01() {
System.out.println("getVal01");//(1)
return 10;
}
public int getVal02() {
System.out.println("getVal02");//(6)
return 10;
}
public A02() {//构造器
//隐藏
//super()
//普通代码和普通属性的初始化...... System.out.println("A02 的构造器");//(7)
}
}
class C02 {
private int n1 = 100;
private static int n2 = 200;
private void m1() {
}
private static void m2() {
}
static {
//静态代码块,只能调用静态成员
//System.out.println(n1);错误
System.out.println(n2);//ok
//m1();//错误
m2();
}
{
//普通代码块,可以使用任意成员
System.out.println(n1);
System.out.println(n2);//ok
m1();
m2();
}
}
class B02 extends A02 { //
private static int n3 = getVal03();
static {
System.out.println("B02 的一个静态代码块..");//(4)
}
public int n5 = getVal04();
{
System.out.println("B02 的第一个普通代码块..");//(9)
}
public static int getVal03() {
System.out.println("getVal03");//(3)
return 10;
}
public int getVal04() {
System.out.println("getVal04");//(8)
return 10;
}
//一定要慢慢的去品.. public B02() {//构造器
//隐藏了
//super()
//普通代码块和普通属性的初始化... System.out.println("B02 的构造器");//(10)
// TODO Auto-generated constructor stub
}
}