- class X
- {
- private Y y=new Y();//此处把y定义为private是为了证明:在子类对象初始化的时候无论父类的变量会不会被子类继承都会被加载(即当父类变量是private也会被先加载)
- X()
- {
- System.out.println("X");
- }
- }
-
- class Y
- {
- Y()
- {
- System.out.println("Y");
- }
- }
- /*
- 定义Y的子类YY是为了区分打印结果中先加载的哪个变量?
- */
- class YY extends Y
- {
- YY()
- {
- System.out.println("y");
- }
- }
-
- class Z extends X
- {
- static Y y=new YY();//定义静态变量是为了证明无论静态变量在子类中或者父类中都是先加载的静态成员变量。
- Y yy=new YY();
- Z()
- {
- super();
- System.out.println("Z");
- }
- public static void main(String args[])
- {
- new Z();
- }
- }
复制代码 【对象初始化过程】
1、因为new用到了.class,所以会先找到.class文件并加载到内存中。
2、执行该类中的static代码块,如果有的话,给.class类进行初始化。
3、在堆内存中开辟空间,分配内存地址。
4、在堆内存中建立对象的特有属性,并进行默认初始化。
5、对属性进行显示初始化。
6、对对象进行构造代码块初始化。
7、对对象进行对应的构造函数初始化。
8、将内存地址赋给占内存中的类变量。
【本题的结论】
这段代码用到的初始化过程主要是第5步:对属性进行显示初始化和第7步:对对象进行对应的构造函数初始化。
本题结果:Yy Y X Yy Z
下面结合结果分析这段代码中子类对象初始化的过程:
1、对静态属性进行初始化:
-》如果子类和父类中有静态变量的话,就先加载静态变量。(这段代码中就是先加载了子类中的static Y y=new YY();所以先打印Yy )
2、对父类中的非静态属性进行初始化:
-》如果没有静态变量或者加载完静态变量后,就会先加载父类中的非静态变量。
(这段代码加载过static Y y之后就加载了父类中的非静态变量 private Y y=new Y();所以打印了Y)
-》特别补充一点:即使父类中的非静态变量是私有的,也会被初始化加载。
3、对父类中进行构造函数初始化:(所以这段代码中接下来打印了X)
4、对子类中的属性进行初始化:(这段代码中接下来加载了子类中的非静态变量Y yy=new YY();所以打印了Yy)
5、对子类中进行构造函数初始化:(所以这段代码中接下来打印了Z)
这样就完成了子类对象的初始化过程 打印结果为YyYXYyZ |