一、代码块
1、概述
代码块:在 Java 中用大括号括起来的代码称为代码块(初始化块)。
2、作用
代码块作用:用来对 Java 类或对象进行初始化。
3、分类
代码块可以使用 static 修饰符修饰,可以分为两类:
静态代码块:一个类中代码块若有修饰符, 则只能被static修饰, 称为静态代码块(static block)
非静态代码块:没有使用static修饰的, 为非静态代码块。
二、非静态代码块
1、格式
[修饰符] class className {
//成员变量
//构造器
//代码块
{
//代码
}
}
2、特点
(1)内部可以有输出语句;
(2)每次都随着对象的创建而执行;
(3)运行时机:每创建一个对象,就执行一次非静态代码块,且先于构造器执行;
(4)作用:可以在创建对象时,对对象的属性等进行初始化;
(5)如果一个类中定义了多个非静态代码块,则按照声明的先后顺序执行;
(6)非静态代码块内可以调用静态的属性、静态的方法,或非静态的属性、非静态的方法;
三、静态代码块
1、使用方式
静态代码块:定义在成员位置,使用 static 修饰的代码块 { }。
位置:类中方法外。
执行:随着类的初始化而且执行且仅执行一次,优先于 main 方法和构造方法的执行。
定义格式:
[修饰符] class className {
//成员变量
//构造器
//代码块
static {
//静态代码块代码
}
}
2、特点
(1)内部可以有输出语句;
(2)随着类的加载而执行,而且只执行一次;
(3)作用:初始化类的信息,例如:用来一次性给静态成员变量进行初始化赋值。
(4)如果一个类中定义了多个静态代码块,则按照声明的先后顺序执行
(5)静态代码块的执行要优先于非静态代码块的执行;
(6)静态代码块内只能调用静态的属性、静态的方法,不能调用非静态的结构;
(7)静态代码块在第一次使用这个类之前执行,即在类的初始化时执行;
案例:
Demo1:
Demo2:
1 class Father {
2 static {
3 System.out.println("11111111111");
4 }
5 {
6 System.out.println("22222222222");
7 }
8
9 public Father() {
10 System.out.println("33333333333");
11
12 }
13
14 }
15
16 public class Son extends Father {
17 static {
18 System.out.println("44444444444");
19 }
20 {
21 System.out.println("55555555555");
22 }
23 public Son() {
24 System.out.println("66666666666");
25 }
26
27
28 public static void main(String[] args) { // 由父及子 静态先行
29 System.out.println("77777777777");
30 System.out.println("************************");
31 new Son();
32 System.out.println("************************");
33
34 new Son();
35 System.out.println("************************");
36 new Father();
37 }
38
39 }
40
41 //结果
42 11111111111
43 44444444444
44 77777777777
45 ************************
46 22222222222
47 33333333333
48 55555555555
49 66666666666
50 ************************
51 22222222222
52 33333333333
53 55555555555
54 66666666666
55 ************************
56 22222222222
57 33333333333
Demo3:
1 class Root{
2 static{
3 System.out.println("Root的静态初始化块");
4 }
5 {
6 System.out.println("Root的普通初始化块");
7 }
8 public Root(){
9 System.out.println("Root的无参数的构造器");
10 }
11 }
12 class Mid extends Root{
13 static{
14 System.out.println("Mid的静态初始化块");
15 }
16 {
17 System.out.println("Mid的普通初始化块");
18 }
19 public Mid(){
20 System.out.println("Mid的无参数的构造器");
21 }
22 public Mid(String msg){
23 //通过this调用同一类中重载的构造器
24 this();
25 System.out.println("Mid的带参数构造器,其参数值:"
26 + msg);
27 }
28 }
29 class Leaf extends Mid{
30 static{
31 System.out.println("Leaf的静态初始化块");
32 }
33 {
34 System.out.println("Leaf的普通初始化块");
35 }
36 public Leaf(){
37 //通过super调用父类中有一个字符串参数的构造器
38 super("尚硅谷");
39 System.out.println("Leaf的构造器");
40 }
41 }
42 public class LeafTest{
43 public static void main(String[] args){
44 new Leaf();
45 //new Leaf();
46 }
47 }
48
49 //结果
50 Root的静态初始化块
51 Mid的静态初始化块
52 Leaf的静态初始化块
53 Root的普通初始化块
54 Root的无参数的构造器
55 Mid的普通初始化块
56 Mid的无参数的构造器
57 Mid的带参数构造器,其参数值:尚硅谷
58 Leaf的普通初始化块
59 Leaf的构造器
总结:程序中成员变量赋值的执行顺序
1、声明成员变量的默认初始化;
2、显式初始化,多个初始化依次被执行(同级别下按先后顺序执行);
3、构造器再对成员进行初始化操作;
4、通过“对象.属性” 或 “对象.方法” 的方式,可多次给属性赋值;