黑马程序员技术交流社区
标题:
在new对象的过程中(没完成创建),能不能创建另一个对象?
[打印本页]
作者:
杨永峰
时间:
2012-6-3 19:52
标题:
在new对象的过程中(没完成创建),能不能创建另一个对象?
本帖最后由 杨永峰 于 2012-6-4 09:14 编辑
class Parent {
public static String psv = tPrint("父类的静态变量初始化了");
public String pv = tPrint("父类普通成员变量初始化了");
static {
System.out.println("父类的静态初始化块初始化了");
}
{
tPrint("父类的初始化块初始化了");
}
public Parent() {
tPrint("父类的构造方法初始化了");
}
public static void sInheritMethod(){
System.out.println("父类的静态InheritMethod");
}
public static void sOverrideMethod(){
System.out.println("父类的Overrid静态方法");
}
public static String tPrint(String str){
System.out.println(str);
return str;
}
public void cInheritMethod(String str_2){
System.out.println(str_2);
}
}
public class SubClass extends Parent {
public static String ssv = tPrint("子类的静态变量初始化了");
//public static SubClass sc_1 = new SubClass();//---------------(1)
//public static Parent sc_5 = new SubClass();// ----------------(5)
public String sv = tPrint("子类的普通成员变量初始化了");
//public SubClass sc_2 = new SubClass();//------------------------(2)
//public Parent sc_4 = new SubClass();//---------------------------(4)
static {
System.out.println("子类的静态初始化块初始化了");
}
{
cInheritMethod("子类的初始化块初始化了");
}
public SubClass() {
cInheritMethod("子类的构造方法初始化了");
}
public static void sOverrideMethod(){
System.out.println("子类重写的静态override方法");
}
public static void main(String[] args) {
//SubClass sc_3 = new SubClass();// ------------------(3)
}
}
复制代码
有继承关系的子类的初始化和对象创建问题:
(1)(2)(3)(4)(5)共5个句子中,哪几个可以同时去掉注释,程序编译、运行正常?其中,解开(2)(3)的注释,会出现死循环,谁能具体解释下?同时解开(1)(3),sc_1和sc_3所指向的对象,哪个最先完成创建?最好能从内存的角度描述子类初始化和创建对象过程中,类和对象中各个成员所属内存的创建顺序、变动。
作者:
罗文杰
时间:
2012-6-3 22:56
本帖最后由 罗文杰 于 2012-6-3 23:44 编辑
占个楼号,这个比较绕,好好分析下,先写下结果。(1)(5)是静态的可以和(3)共存,(2)(4)绝对不能和(3)共存(或者说(2)(3)(4)不能共存)。
首先静态一定会先执行,那么执行的顺序是什么?
首先分析(1)和(5)的初始化过程,这两个是一样的,都是静态的。不管你运不运行(3),(1)和(5)都会先初始化。
首先(1)执行的时候去找父类,父类里面有静态的就先初始化,初始化完成后,子类里面的静态的就初始化,***但是这里要注意 ***,子类的静态代码块不执行,因为子类的静态代码块 放在(1),(5)的后面,这时(1),(5)被当成是一个静态变量去执行,所有的步骤都是在子类静态代码块之前来完成,但是你把子类的静态代码块放在(1),(5)之前,(1)会先在执行完父类的静态的初始化之后,去执行子类的静态代码块,但是(5)不会执行,因为静态代码块只执行一次!
静态的东西初始化完毕之后,就执行非静态的东西,按照以下顺序执行(你在初始化(1),(5)的过程中,下面的步骤都是做为静态的形式体现的,因为(1),(5)被当成是静态变量 ):
1.先为成员变量分配空间,设置成员的值为默认的初始值(0,false,null)
2.调用对象的构造方法(但是还没有执行构造方法体)
3.隐式或显式调用父类的构造方法(但是还没有执行构造方法体)
4.执行父类的非静态代码块
5.执行父类的构造方法。
6.使用初始化程序和初始块初始化成员。
7.执行子类的非静态代码块
8.执行子类的构造函数
别忘了最后一步,执行子类的子类的静态代码块(如果没有执行过的话)。
关于(2),(3),(4)初始化过程是一样的。
初始化的过程去先去执行父类的静态的东西,然后执行子类静态的东西,(如上所示)静态的都执行完毕后,按照上面写的1-8的步骤来执行非静态的内容。
至于为什么不能共存,当你去初始化 (3)的过程中会在初始化非静态变量的时候上述步骤所示的第6这个步骤去new一个子类对象,这个时候又返回1的步骤,在1到6的步骤中一直循环的new子类对象,永远执行不到7,8的步骤,相信你在运行结果里会看到,子类的非静态代码块和构造函数永远都执行不到,所以你永远都不能初始化一个子类对象,只能在内存空间中去无限的new子类,程序运行一阵儿,内存那哥们就要画圈圈诅咒你了~~~{:soso_e127:}
(以上是个人见解,如有纰漏,望请指正,谢谢~)
作者:
罗文杰
时间:
2012-6-4 07:11
忘了加,同理(1)(5)和(2)(4)也不能共存。
作者:
闾丘日月
时间:
2012-6-4 09:07
先占个楼,这个问题很有意思。
作者:
郭宁
时间:
2012-6-4 09:11
好吧都占楼~ 我也前排占位!
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2