子类对象初始化过程
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------
1. 子类对象的初始化过程
1). 执行顺序
有继承的时候,调用子类构造方法之后,运行到子类构造函数第一行之后, 执行顺序如下:
(1). 父类静态相关初始化(仅仅执行一次)
{1}. 父类的静态成员显式初始化(仅执行一次)--->
{2}. 父类的静态成员隐式初始化(仅执行一次)
//静态成员也是子类继承的对象
{3}. 父类static代码块(仅执行一次)--->
//执行的原理就是静态代码块可能初始化子类要继承的父类的静态变量
(2). 子类静态相关初始化(仅仅执行一次)
{1}. 子类的静态成员初始化(仅执行一次)--->
{2}.子类的静态成员初始化(仅执行一次)--->
{3}. 子类static代码块(仅执行一次)--->
//静态先执行的原因就是随着相应的类加载而加载,并且静态代码块没有名字,不能被调用,//所以也要立刻执行。
(3). 父类非静态相关初始化
{1}. 父类成员变量隐式初始化--->
{2}. 父类成员变量显式初始化--->
{3}. 父类构造代码块 ---> //这步可能涉及到父类成员变量的初始化,所以要执行
{4}. 父类构造方法初始化 ---> //执行这步的原理同上
(4). 子类非静态相关初始化
{1}. 子类成员变量隐式初始化--->
{2}. 子类成员变量显式初始化--->
{3}. 子类构造代码块
{4}. 子类构造方法初始化
【总结】子类对象初始化要做的事情的核心就是:
只要是涉及到子类自身的数据(静态或者非静态)以及需要从父类继承的数据(静态或者非静态)的初始化动作,就一定要执行。
2). 范例
class Fu{
int fuInt=10;
StringfuStr;
static int fuStaticInt;
static String fuStaticStr ="Fu Static";
static{
System.out.println("fu static code block..."+ fuStaticInt +":::::"+ fuStaticStr);
}
{
System.out.println("fu codeblock..."+ fuInt+":::::"+fuStr);
}
Fu(){
fuInt =20;
fuStr ="Ben";
System.out.println("fu constructor..."+ fuInt+"***"+ fuStr+"...without parameters");
}
Fu(int fuInt, String fuStr){
this.fuInt =fuInt;
this.fuStr =fuStr;
System.out.println("fu constructor..."+ fuInt+"***"+ fuStr+"...with parameters");
}
}
class Zi extends Fu{
int ziInt=30;
StringziStr;
static int ziStaticInt;
static String ziStaticStr ="Zi Static";
static{
System.out.println("zi static code block..."+ ziStaticInt +":::::"+ ziStaticStr);
}
{
System.out.println("zi codeblock..."+ ziInt+":::::"+ziStr);
}
Zi(){
ziInt =20;
ziStr ="BenZi";
System.out.println("zi constructor..."+ ziInt+"***"+ ziStr+"...without parameters");
}
Zi(int ziInt, String ziStr){
this.ziInt =ziInt;
this.ziStr =ziStr;
System.out.println("zi constructor..."+ ziInt+"***"+ ziStr+"...with parameters");
}
}
class Test{
public static void main(String[] args) {
Zizi =new Zi();
System.out.println("*****************************");
ZiziII =new Zi(100, "ZXM");
}
}
运行结果:
3). 练习题
求输出结果
class Y {
Y(Stringname) {
System.out.print("Y--"+name);
}
}
class X {
Y b = new Y("Fu");
X(){
System.out.print("X");
}
}
public class Test2 extends X {
Y y = new Y("Zi");
Test2(){
System.out.print("Zi");
}
public static void main(String[] args) {
new Test2();
}
}
这里注意一下:当父类出现的时候,不能单纯的看子类的执行过程,因为父类中的数据是子类要继承的,必须全部先准备好。所以不是子类的Y y = new Y("Zi");先执行。
*Y--Fu*X*Y--Zi*Zi
父类的显式初始化 ---> 父类的构造函数--->子类的显式初始化 --->子类构造函数
----------- android培训、java培训、java学习型技术博客、期待与您交流! ------------