文章目录
- 代码块的描述
- 静态代码块
- 静态代码块的特点
 
- 非静态代码块
- 分析加载顺序
代码块的描述
-  代码块(或初始化块)的 作用:
-  对Java类或对象进行初始化 
-  代码块(或初始化块)的 分类:-  一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块(static block) 
-  没有使用static修饰的,为非静态代码块。 
 
-  
静态代码块
如果想要为静态变量初始化,可以直接在静态变量的声明后面直接赋值,也可以使用静态代码块。
- 在代码块的前面加static,就是静态代码块。
【修饰符】 class 类{
	static{
        静态代码块
    }
}
静态代码块的特点
-  可以有输出语句。 
-  可以对类的属性、类的声明进行初始化操作。 
-  不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。 
-  若有多个静态的代码块,那么按照从上到下的顺序依次执行。 
-  静态代码块的执行要先于非静态代码块。 
-  静态代码块随着类的加载而加载,且只执行一次。 
public class Chinese {
//    private static String country = "中国";
    private static String country;
    private String name;
    {
        System.out.println("非静态代码块,country = " + country);
    }
    static {
        country = "中国";
        System.out.println("静态代码块");
    }
    public Chinese(String name) {
        this.name = name;
    }
}
public class TestStaticBlock {
    public static void main(String[] args) {
        Chinese c1 = new Chinese("张三");
        Chinese c2 = new Chinese("李四");
    }
}
输出结果:
静态代码块
非静态代码块,country = 中国
非静态代码块,country = 中国
结论:静态代码有类则运行,非静态有对象在运行
非静态代码块
语法格式
【修饰符】 class 类{
    {
        非静态代码块
    }
    【修饰符】 构造器名(){
    	// 实例初始化代码
    }
    【修饰符】 构造器名(参数列表){
        // 实例初始化代码
    }
}
- 和构造器一样,也是用于实例变量的初始化等操作。
- 如果多个重载的构造器有公共代码,并且这些代码都是先于构造器其他代码执行的,那么可以将这部分代码抽取到非静态代码块中,减少冗余代码。
- 特点如下:
-  可以有输出语句。 
-  可以对类的属性、类的声明进行初始化操作。 
-  除了调用非静态的结构外,还可以调用静态的变量或方法。 
-  若有多个非静态的代码块,那么按照从上到下的顺序依次执行。 
-  每次创建对象的时候,都会执行一次。且先于构造器执行。 
小结:实例变量赋值顺序
 
分析加载顺序
/**
 * ClassName: ll
 * Package: PACKAGE_NAME
 * Description:
 *
 * @Author Thmiao
 * @Create 2023/7/11 01:35
 * @Version 1.0
 */
class Root{
    static{
        System.out.println("Root的静态初始化块");
    }
    {
        System.out.println("Root的普通初始化块");
    }
    public Root(){
        System.out.println("Root的无参数的构造器");
    }
}
class Mid extends Root{
    static{
        System.out.println("Mid的静态初始化块");
    }
    {
        System.out.println("Mid的普通初始化块");
    }
    public Mid(){
        System.out.println("Mid的无参数的构造器");
    }
    public Mid(String msg){
        //通过this调用同一类中重载的构造器
        this();
        System.out.println("Mid的带参数构造器,其参数值:"
                + msg);
    }
}
class Leaf extends Mid{
    static{
        System.out.println("Leaf的静态初始化块");
    }
    {
        System.out.println("Leaf的普通初始化块");
    }
    public Leaf(){
        //通过super调用父类中有一个字符串参数的构造器
        super("参数啊");
        System.out.println("Leaf的构造器");
    }
}
public class LeafTest{
    public static void main(String[] args){
        new Leaf();
        //new Leaf();
    }
}
运行结果:
Root的静态初始化块
Mid的静态初始化块
Leaf的静态初始化块
Root的普通初始化块
Root的无参数的构造器
Mid的普通初始化块
Mid的无参数的构造器
Mid的带参数构造器,其参数值:参数啊
Leaf的普通初始化块
Leaf的构造器
比较运行顺序2
class Father {
    static {
        System.out.println("11111111111");
    }
    {
        System.out.println("22222222222");
    }
    public Father() {
        System.out.println("33333333333");
    }
}
public class Son extends Father {
    static {
        System.out.println("44444444444");
    }
    {
        System.out.println("55555555555");
    }
    public Son() {
        System.out.println("66666666666");
    }
    public static void main(String[] args) {
        System.out.println("77777777777");
        System.out.println("************************");
        new Son();
        System.out.println("************************");
        new Son();
        System.out.println("************************");
        new Father();
    }
}
运行结果:
11111111111
44444444444
77777777777
************************
22222222222
33333333333
55555555555
66666666666
************************
22222222222
33333333333
55555555555
66666666666
************************
22222222222
33333333333



















