【知识点】Java类初始化顺序总结

本文深入解析Java类的初始化过程,包括静态与普通属性、方法块、构造函数的执行顺序,父类与子类、接口、抽象类及实现类的初始化流程,以及多态和方法覆盖的实践案例。

一、类的结构:

  1. 静态属性:static 开头定义的属性
  2. 静态方法块: static {} 圈起来的方法块
  3. 普通属性: 未带static定义的属性
  4. 普通方法块: {} 圈起来的方法块
  5. 构造函数: 类名相同的方法
  6. 方法: 普通方法
public class Test {
    // 静态属性
    private static String staticField = getStaticField();
    // 静态方法块
    static {
        System.out.println("静态方法块初始化");
    }
    // 普通属性
    private String field = getField();
    // 普通方法块
    {
        System.out.println("普通方法块初始化");
    }
    // 构造函数
    public Test() {
        System.out.println("构造函数初始化");
    }

    public static String getStaticField() {
        String statiFiled = "静态属性初始化";
        System.out.println("静态属性初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "普通属性初始化";
        System.out.println("普通属性初始化");
        return filed;
    }  
    
    public static void main(String[] args) {
		new Test();
	}
}

执行结果:

静态属性初始化
静态方法块初始化
普通属性初始化
普通方法块初始化
构造函数初始化

二、父类与子类的初始化顺序

class Father {
    // 静态属性
    private static String staticField = getStaticField();
    // 静态方法块
    static {
        System.out.println("父类静态方法块初始化");
    }
    // 普通属性
    private String field = getField();
    // 普通方法块
    {
        System.out.println("父类普通方法块初始化");
    }
    // 构造函数
    public Father() {
        System.out.println("父类构造函数初始化");
    }

    public static String getStaticField() {
        String statiFiled = "父类静态属性初始化";
        System.out.println("父类静态属性初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "父类普通属性初始化";
        System.out.println("父类普通属性初始化");
        return filed;
    }  
    
    public void method() {
    	System.out.println("父类普通方法");
    }
    
    public void method2() {
    	System.out.println("父类普通方法2");
    }
}

class Son extends Father{
	// 静态属性
    private static String staticField = getStaticField();
    // 静态方法块
    static {
        System.out.println("子类静态方法块初始化");
    }
    // 普通属性
    private String field = getField();
    // 普通方法块
    {
        System.out.println("子类普通方法块初始化");
    }
    // 构造函数
    public Son() {
        System.out.println("子类构造函数初始化");
    }

    public static String getStaticField() {
        String statiFiled = "子类静态属性初始化";
        System.out.println("子类静态属性初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "子类普通属性初始化";
        System.out.println("子类普通属性初始化");
        return filed;
    }  
    
    public void method() {
    	System.out.println("子类普通方法");
    }
}

public class Test2{
	public static void main(String[] args) {
		new Son();
	}
} 

执行结果:

父类静态属性初始化
父类静态方法块初始化
子类静态属性初始化
子类静态方法块初始化
父类普通属性初始化
父类普通方法块初始化
父类构造函数初始化
子类普通属性初始化
子类普通方法块初始化
子类构造函数初始化


拓展一、声明一个子类引用调用method()

Son son = new Son();
son.method();

执行结果:

子类普通方法

拓展一总结:子类引用调用的是子类的方法;

拓展二、父类向下转型

Father father = new Son();
father.method();
father.method2();

执行结果:

子类普通方法

父类普通方法2

拓展二总结:父类向下转型(多态),如果子类重载了父类的方法,向下转型的父类会调用子类重载后的方法,如果子类中没有重载父类的方法,则是会去调用父类的方法。

三、接口,抽象类,实现类初始化顺序

interface Interface{
	static String InterfaceStaticField = "接口静态属性";
}

abstract class Abstract implements Interface{
	// 静态属性
    private static String AbstractStaticField = getStaticField();
    // 静态方法块
    static {
        System.out.println("抽象类静态方法块初始化");
    }
    // 普通属性
    private String field = getField();
    // 普通方法块
    {
        System.out.println("抽象类普通方法块初始化");
    }
    // 构造函数
    public Abstract() {
        System.out.println("抽象类构造函数初始化");
    }

    public static String getStaticField() {
    	System.out.println(InterfaceStaticField);
        String statiFiled = "抽象类静态属性初始化";
        System.out.println("抽象类静态属性初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "抽象类普通属性初始化";
        System.out.println("抽象类普通属性初始化");
        return filed;
    }  
    
    public void method() {
    	System.out.println("抽象类普通方法");
    }
}

class InterfaceAndAbstract extends Abstract {
	// 静态属性
    private static String InterfaceAndAbstract = getStaticField();
    // 静态方法块
    static {
        System.out.println("实现类静态方法块初始化");
    }
    // 普通属性
    private String field = getField();
    // 普通方法块
    {
        System.out.println("实现类普通方法块初始化");
    }
    // 构造函数
    public InterfaceAndAbstract() {
        System.out.println("实现类构造函数初始化");
    }

    public static String getStaticField() {
        String statiFiled = "实现类静态属性初始化";
        System.out.println("实现类静态属性初始化");
        return statiFiled;
    }

    public static String getField() {
        String filed = "实现类普通属性初始化";
        System.out.println("实现类普通属性初始化");
        return filed;
    }  
    
    public void method() {
    	System.out.println("实现类普通方法");
    }
}

public class Test3 {
	public static void main(String[] args) {
		new InterfaceAndAbstract();
	}
}

执行结果:

接口静态属性
抽象类静态属性初始化
抽象类静态方法块初始化
实现类静态属性初始化
实现类静态方法块初始化
抽象类普通属性初始化
抽象类普通方法块初始化
抽象类构造函数初始化
实现类普通属性初始化
实现类普通方法块初始化
实现类构造函数初始化

四、总结

类的初始化顺序:静态  >   普通

                             接口  >  抽象类  >  实现类

                             静态属性  >  静态方法块  >  普通属性  >   普通方法块  >  构造方法

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值