那些你还不熟悉的---类的初始化和实例化的初始化过程

面试题:
如下两个类的代码

/*父类对象*/
public class Father{
	private int i = test();
	private static int j = method();
	static{
		System.out.print("(1)");
	}

	Father(){
		System.out.print("(2)");
	}
	{
		System.out.print("(3)");
	}
	
	
	public int test(){
		System.out.print("(4)");
		return 1;
	}
	public static int method(){
		System.out.print("(5)");
		return 1;
	}
}
/*子类对象*/
public class Son extends Father{
	private int i = test();
	private static int j = method();
	static{
		System.out.print("(6)");
	}
	Son(){
		System.out.print("(7)");
	}
	{
		System.out.print("(8)");
	}
	public int test(){
		System.out.print("(9)");
		return 1;
	}
	public static int method(){
		System.out.print("(10)");
		return 1;
	}
	public static void main(String[] args) {
		Son s1 = new Son();
		System.out.println();
		Son s2 = new Son();
	}
}

问题:

  1. 执行Son类的main函数,控制台打印的结果是什么?
  2. 如果main方法什么都不写,控制台打印的结果是什么?

结果

第一题答案:

(5)(1)(10)(6)(9)(3)(2)(9)(8)(7)
(9)(3)(2)(9)(8)(7)

第二题答案:

(5)(1)(10)(6)

你是否答对了?

类的初始化过程

使用到一个类对其进行实例化就需要先对类进行初始化,而且类的初始化只执行一次!这个特点可以做单例模式
类的初始化就是将静态成员变量静态代码块进行初始化,静态代码块和静态成员变量的执行顺序按照代码的先后顺序执行,谁在上面就谁先执行初始化!

注意:main方法所在的类先加载和初始化,该类的初始化又要先初始化父类

也就是说最先初始化的类是父类的静态代码块或者静态成员变量,然后是子类的静态代码块或者静态成员变量静态代码块和静态成员变量的先后顺序由代码先后顺序影响

实例化的初始化过程

一个类要进行实例化,就需要先对类初始化然后再实例化,实例化又需要先实例化父类,后实例化子类
实例化需要初始化非静态成员变量非静态代码块,非static的成员变量和代码块的先后顺序也是谁先声明谁先执行。
最后执行构成方法

总结

整体的初始化排序
类初始化 > 实例化初始化


**父类**静态成员变量 或 静态代码块(顺序由声明先后顺序定)>
**子类**静态成员变量 或 静态代码块(顺序由声明先后顺序定)>
**父类**非静态成员变量 或 非静态代码块(顺序由声明先后顺序定)>
父类构造方法>
**子类**非静态成员变量 或 非静态代码块(顺序由声明先后顺序定)>
子类构造方法

如果以16进制的方式去查看编译后的class文件会发现有<clinit>、<init>等方法
而<clinit>()就是进行类初始化执行的指令,里面由 静态类成员变量显示赋值 和 静态代码块 组成,里面的顺序按照声明顺序先后执行
<init>()可能有多个,因为有无参构造器和有参构造器,有几个构造器就有几个<init>()。是执行示例化初始化的指令,里面由 非静态类成员变量显示赋值 和 非静态代码块 组成,里面的顺序按照声明顺序先后执行,<init>()首行一定是super();构造器里的代码最后执行。每一次实例化都执行一次<init>()

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章