简析程序执行过程(小例子)

程序貌似是Java程序思想上的 

/*
@TODO 程序执行过程*/

class Base
{
	static int s1 = prt("s1 initialized.", 11);
	int i1 = prt("i1 initialized.", 12);
	Base()
	{
		System.out.println("Base()");
		System.out.println("s1 = " + s1 + ", i1 = " + i1);
		draw();
	}
	void draw()
	{
		System.out.println("Base.draw:s1= " + s1 + " ,i1 = " + i1);
	}
	static int prt(String s,int num)
	{
		System.out.println(s);
		return num;
	}
}

class Cleanser extends Base
{
	static int s2 = prt("s2 initialized.", 21);
	int i2 = prt("i2 initialized.", 22);
	Cleanser()
	{
		System.out.println("Cleanser()");
		System.out.println("s2 = " + s2 + ", i2 = " + i2);
	}
	Cleanser(String a)
	{
		System.out.println("Cleanser(" + a + ")");
		System.out.println("s2 = " + s2 + ", i2 = " + i2);
	}
	void draw()
	{
		System.out.println("Cleanser.draw:s2 = " + s2 + ", i2 = " + i2);
	}
}

public class ExplicitStatic extends Cleanser
{
	static int s3 = prt("s3 initialized.", 31);
	int i3 = prt("i3 initialized.", 32);
	ExplicitStatic()
	{
		super("ExplicitStatic");
		System.out.println("ExplicitStatic");
		System.out.println("s3 = " + s3 + ", i3 = " + i3);
	}
	public static void main(String[] args)
	{
		ExplicitStatic x = new ExplicitStatic();
	}
	
}

 

输出结果:

s1 initialized.
s2 initialized.
s3 initialized.
i1 initialized.
Base()
s1 = 11, i1 = 12
Cleanser.draw:s2 = 21, i2 = 0
i2 initialized.
Cleanser(ExplicitStatic)
s2 = 21, i2 = 22
i3 initialized.
ExplicitStatic
s3 = 31, i3 = 32

 

引用自: www.codepub.com 源码网资料Java编程思想读书笔记

初始化顺序为:
1)    加载代码(.class文件)
2)    初始化class的静态成员,初始化顺序了“从里到外”,即从base class开始。
3)    在derived class的构造函数中调用base class的构造函数。
如果在derived class的构造函数中没有通过super()显式调用调用base class的构造函数,编译器会调用bass class的default构造函数并自动生成相应的调用语句,从而产生一个base class实例。如果在derived class的构造函数中通过super()显示调用了父类的构造函数,则调用所指定的构造函数。调用构造函数的调用顺序是“从里到外”。
4)    调用derived class的构造函数。
**:当base class没有default构造函数时,必须在derived class的构造函数中通过super显示调用base class的构造函数。
例:下面代码的初始化过程为:
1)    装载ExplicitStatic的代码(装载ExplicitStatic.class文件)。
2)    发现ExplicitStatic有关键字extends,装载ExplicitStatic的base class的代码(装载Cleanser.class文件)。
3)    发现Cleanser有关键字extends,装载Cleanser的base class的代码(装载Base.class文件)。
4)    初始化Base class中的静态成员。
5)    初始化Cleanser class中的静态成员。
6)    初始化ExplicitStatic class中的静态成员。
如果把(c)处的代码注释掉,那么初始化工作到此就结束了。
7)    为ExplicitStatic对象分配存储空间,并把存储空间初始化为0。
8)    在ExplicitStatic class的构造中调用super("ExplicitStatic")(在ExplicitStatic class的构造函数中显式调用父类的构造函数),试图产生一个Cleanser class实例。
9)    为Cleanser对象分配存储空间,并把存储空间初始化为0。
10)    由于Cleanser class又是继承自Base class,会在Cleanser class的构造函数中通过super()(由于没有显式调用父类的构造函数,所以自动调用父类的default构造函数)调用父类的构造函数,试图产生一个Cleanser class实例。
11)    产生一个Base class实例。先初始化成员变量,再调用构造函数。
12)    回到Cleanser class,产生一个实例。首先初始化Cleanser class中的成员数据,再执行构造函数Cleanser(String a)中的其余部分。
13)    回到ExplicitStatic class,产生一个实例。首先初始化ExplicitStatic class中的成员数据,再执行构造函数ExplicitStatic ()中的其余部分(System.out.println(“ExplicitStatic()”))。

 

结果中: Cleanser.draw:s2 = 21, i2 = 0

由于在Base()中调用draw()时,Cleanser中的i2还未进行初始化,而在为Cleanser对象分配存储空间时,把存储空间初始化为0,所以此时i2为0。

你可能感兴趣的:(编程,读书)