您的位置:首页 > 编程语言 > Java开发

java类初始化中类成员的执行顺序解析

2016-10-27 21:16 218 查看

java类初始化中类成员的执行顺序解析

java初始化过程中,代码块,static代码块,实例成员变量,static变量,static方法和普通方法初始化顺序是怎样的呢?

首先看一段代码块,分析其输出打印结果

public class App
{
private static App d = new App();
private SubClass t = new SubClass();
static
{
System.out.println(3);
}
{
System.out.println(5);
}
{
System.out.println(6);
}
public App()
{
System.out.println(4);
}
public static void main(String[] args)
{
System.out.println("hello");
}
}

class SuperClass//父类
{
SuperClass()
{
System.out.println("构造器SuperClass");
}
static
{
System.out.println("superclass静态初始化");
}
}

class SubClass extends SuperClass   //子类
{
static
{
System.out.println(1);
}
{
System.out.println(7);
}
public SubClass()
{
//super();
System.out.println(2);
}
}


打印出的答案为:



为什么是这样的结果呢 ??

首先java中共有三种代码块:局部代码块,初始化代码块,静态初始化代码块

1.此题局部代码块不在我们考虑范围

2.初始化代码块(构造代码块):直接定义在类中

每次创建对象的时候都会先执行初始化代码块,通过反编译看到其本质是放到构造器中super()构造器后执行,优先于本类构造器代码先执行,完成初始化.

3.静态初始化代码块:使用static修饰的普通初始化代码块

所在类被加载时按顺序加载到的时候才执行初始化,优先于main方法执行

并且我们先记住3点

1.static修饰的变量和方法是随class的加载而加载并完成初始化的

2.static修饰的变量和方法是按照顺序加载的

3.实例变量是通过new调用构造器创建实例的时候才开始执行初始化的

好接下来我们来分析初始化过程:

1.首先第一步先加载第一个static语句,d声明后储存在方法区中,并调用构造器创建App实例

2.此时构造器会加载非静态变量

①.发现SubClass类型变量,先去包中寻找相关的类,找到SubClass后,再去找其父类SuperClass

②.找到SubClass所有关联类之后,先加载父类字节码文件,此时SuperClass(static代码块完成初始化,打印”superclass静态初始化”),然后再加载SubClass(加载时完成初始化,打印出”1”);

3.加载完关联类之后,调用SubClass构造器,SubClass构造器会默认先调用super()父类构造器输出(“构造器SuperClass”父类构造器总是在子类构造器第一行调用),

然后开始执行子类初始化代码段,其本质是在构造器中初始化,在父类构造器后执行,优先于子类构造器内容执行,输出代码“7”,然后执行子类构造器中代码输出”2”.

4.然后按顺序执行App构造器中初始化代码块,输出“5”“6”,然后执行构造器App()中代码,输出4;

5.实例变量加载完之后,按顺序加载static变量,此时开始加载static代码块,输出3.

6.在加载字节码文件最后执行main方法,输出”hello”

分析完成

最后,按照以上思路,大家分析一下下面代码的打印结果:

public class App
{
private static App d  = null;//stataic字段的初始化,
{System.out.println("代码块啊");}
private SubClass t = new SubClass();//非static字段的初始化其实都在构造器中,优先执行的.

static
{
d = new App();
System.out.println(3);
}

public App()
{
//t = new SubClass();
//-----------------------------------
System.out.println(4);
}

public static void main(String[] args)
{
System.out.println("Hello");
}
}

//父类
class SuperClass
{
SuperClass()
{
System.out.println("构造SuperClass");
}
}

//子类
class SubClass extends SuperClass
{
static
{
System.out.println(1);
}

SubClass()
{
//super();//表示调用父类无参数构造器
System.out.println(2);
}
}


运行结果为下图:



大家分析一下能否得到这个结果。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息