Java初始化执行顺序

初始化的作用:

初始化分为两种

  • (1)类初始化:执行一个叫做<clinit>()类初始化方法 cl = class ,init = initialize
  • (2)实例初始化:执行对应的<init>(【…】)实例初始化方法
    • 初始化相关的方法不是程序员手动编写的,而是编译器自动组装生成的。
    • 类初始化优先于实例初始化

类初始化方法

  • 1、为静态变量初始化的。

  • 2、类初始化就是执行<clinit>()类初始化方法,这个方法是由编译器组装某些代码而成。它由:

    • (1)静态变量的显式赋值语句
    • (2)静态代码块
    • 两部分组成。至于(1)和(2)谁先执行,看它们声明的先后位置。
  • 3、类初始化方法什么时候执行?以及执行的特点?

    • (1)当某个类第一次被使用时,这个类会被加载并且初始化。
      • 如main方法所在的类,要先完成类初始化,再执行main方法。
    • (2)一个类的类初始化方法只会执行一次
    • (3)类初始化方法优先于实例初始化方法
    • (4)子类初始化时,如果发现父类还没有初始化,会先初始化父类
      在这里插入图片描述
      根据刚才所说,大家可以推一下以下代码的运行结果
public class TestClassInitialize {
	public static void main(String[] args) {
		ClassInitialize c1 = new ClassInitialize();
		ClassInitialize c2 = new ClassInitialize();
		ClassInitialize c3 = new ClassInitialize();
		ClassInitialize c4 = new ClassInitialize();
		
		ClassInitialize.test();
		ClassInitialize.test();
	}
}
class ClassInitializeFather{
	//静态代码块
	static{
		System.out.println("父类静态代码块1");
		System.out.println("a = " + ClassInitializeFather.a);
		//如果在编写代码时,你要先于声明使用,加“类名."
	}
	
	private static int a = getA();
	private static int b = getB();
	
	static{
		System.out.println("父类的静态代码块2");
	}
	
	
	public static int getA(){
		System.out.println("父类的getA()");
		return 1;
	}
	public static int getB(){
		System.out.println("父类的getB()");
		return 2;
	}
}
class ClassInitialize extends ClassInitializeFather{
	private static int num = getNum();
	
	//静态代码块
	static{
		System.out.println("子类静态代码块");
	}
		
	public ClassInitialize(){
		System.out.println("ClassInitialize构造器");
	}
	
	/*
	 * 这里用getNum()方法的返回值,为静态变量num赋值,
	 * 同时查看这个赋值操作执行的情况。
	 */
	public static int getNum(){
		System.out.println("getNum被执行了");
		return 10;
	}
	
	public static void test(){
		System.out.println("ClassInitialize的静态方法");
	}
}

实例初始化方法

  • 1、给实例变量赋值

  • 2、实例初始化的方法<init>()是由三部分的代码组成:

    • (1)非静态变量(实例变量)的显式赋值
    • (2)非静态代码块
    • (3)构造器
    • 并且一个类至少有一个实例初始化方法,也可能很多个,实例初始化方法的个数由构造器的个数决定。
    • 其中这三部分来说,(1)和(2)是按顺序组装。(3)构造器中的代码一定是最后。
  • 3、什么时候执行?执行的特点是什么?

    • (1)你每new一个对象,就会执行一个实例初始化方法。
      • 每次调用哪个实例初始化方法,看你调用哪个构造器。
    • (2)要执行子类的实例初始化方法,会先执行父类相应的实例初始化方法
      在这里插入图片描述
      根据刚才所说,大家可以推一下以下代码的运行结果
public class TestInstanceInitialize {
	public static void main(String[] args) {
		new Instance();
		//new Instance(2);
	}
}
class Fu{
	private int a = getA();
	{
		System.out.println("(1)父类的非静态代码块");
	}
	public Fu(){
		System.out.println("(2)父类无参构造");
	}
	public Fu(int i){
		System.out.println("(3)父类有参构造");
	}
	public int getA(){
		System.out.println("(4)父类getA()");
		return 1;
	}
}
class Instance extends Fu{
	
	public Instance(){
		System.out.println("(5)子类无参构造器");
	}
	public Instance(int a){
		this.a = a;
		System.out.println("(6)子类有参构造器");
	}
	
	//非静态代码块
	{
		System.out.println("(7)子类非静态代码块");
	}
	
	private int a  = getA();
	
	public int getA(){
		System.out.println("(8)子类getA()");
		return 1;
	}
	
	public static void test(){
		System.out.println("静态方法");
	}
}

类初始化和实例初始化的总结:

  • (1)父类的类初始化

  • (2)子类的类初始化

  • (3)父类的对应的实例初始化

  • (4)子类的对应的实例初始化

  • A:顺序(1)(2)(3)(4)

  • B:其中的(1)(2)只会执行一次;(3)(4)每new一个对象就执行一次。

  • C:子类构造器中如果没有super()或super(实参列表)表示执行的是父类的无参的实例初始化方法<init>()

  • 如果子类的构造器中有super()或super(实参列表)表示执行对应的实例初始化方法

  • D:如果在实例初始化过程中,涉及到调用某个方法,那么如果这个方法没有static修饰,要考虑是否被子类重写了。
    (如果这个方法有static修饰,不会被重写,在哪个类中,就执行哪个类的)

  • 类初始化的方法的由两部分组成:

    • (1)静态变量的显式赋值
    • (2)静态代码块
    • 它俩按顺序执行。
  • 实例初始化方法由三部分组成:

    • (1)非静态变量的显式赋值
    • (2)非静态代码块
    • (3)构造器
    • 其中(1)和(2)按顺序,(3)在最后。但是(3)中的super()或super(实参列表)被组装到实例初始化方法中也在首行。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值