文章目录
- 前言
- 一、对象初始化步骤
- 二、实例
- 三、特殊案例
- 四、枚举类初始化
前言
在面向对象的编程语言中,了解对象初始化的步骤有利于我们更好地写成代码。
一、对象初始化步骤
- 父类静态变量、静态代码块初始化
- 子类静态变量、静态代码块初始化
- 父类变量、代码块初始化
- 父类构造方法
- 子类变量、代码块初始化
- 子类构造方法
注意:
1:所有的静态变量,静态代码块只会在第一次创建对象时进行初始化
2:变量和代码块的初始化过程是按照在类中定义的顺序执行的,如变量a,代码块b,变量c,则初始化过程为a->b->c,不是a->c->b(静态变量和静态代码块同理)
二、实例
注意public Father()和public Son()两行的注释。
class Father{
public int num2=4;//5
public Father(){//调用构造方法时转到5,去完成变量和代码块的初始化,结束后执行7
//7
System.out.println("父类构造函数初始化");
}
{//6
System.out.println("父类代码块初始化");
}
static {//1
System.out.println("父类静态代码块初始化");
}
public static int num1=2;//2
}
class Son extends Father{
public static int num3=6;//3
public Son(){ //调用构造方法时转到父类构造方法处,父类初始化完成后,去完成变量和代码块的初始化,结束后执行10
//10
System.out.println("子类构造函数初始化");
}
{//8
System.out.println("子类代码块初始化");
}
public int num4=8;//9
static {//4
System.out.println("子类静态代码块初始化");
}
}
public class initializeDemo {
public static void main(String[] args) {
Son son = new Son();
}
/*
执行结果:
父类静态代码块初始化
子类静态代码块初始化
父类代码块初始化
父类构造函数初始化
子类代码块初始化
子类构造函数初始化
*/
}
三、特殊案例
如果一个类的静态变量f2创建了该类的对象,则初始化流程有所不同(如果f2创建的不是该类的对象,则f2按照一中所说的步骤执行),此时f2不会执行一中的1.2步。
class Father{
public int num2=4;
public static Father f2=new Father();//对f1的静态变量f2(如果此时f2和f1是同一类的对象)进行初始化时,会先对f2中的非静态代码进行初始化,结束后再按照对象初始化步骤依次执行
public Father(){
System.out.println("构造函数初始化");
}
{
System.out.println("代码块初始化");
}
static {
System.out.println("静态代码块初始化");
}
}
public class initializeDemo {
public static void main(String[] args){
Father f1 = new Father();
}
/*
执行结果:
代码块初始化
构造函数初始化
静态代码块初始化
代码块初始化
构造函数初始化
*/
}
四、枚举类初始化
在第一次创建枚举类对象时,会一次性初始化所有枚举常量(并不是创建哪个枚举常量就初始化哪个),之后再创建枚举类对象时不再调用构造方法。
enum Mark {
bad("0-60"),common("61-80"),good("81-100");
private String markRange;
Mark(String m) {
markRange= m;
System.out.println("初始化完成:"+m);
}
String getMarkRange() {
return markRange;
}
}
public class initializeDemo {
public static void main(String[] args) {
Mark good = Mark.good;
System.out.println("===========");
Mark bad = Mark.bad;
}
/*
执行结果:
初始化完成:0-60
初始化完成:61-80
初始化完成:81-100
===========
*/
}