A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 杨永峰 于 2012-6-4 09:14 编辑
  1. class Parent {

  2.         public static String psv = tPrint("父类的静态变量初始化了");
  3.         public String pv = tPrint("父类普通成员变量初始化了");
  4.         
  5.         static {
  6.                 System.out.println("父类的静态初始化块初始化了");
  7.         }
  8.         {
  9.                 tPrint("父类的初始化块初始化了");
  10.         }
  11.         
  12.         public Parent() {
  13.                 tPrint("父类的构造方法初始化了");
  14.         }
  15.         
  16.         
  17.         public static void sInheritMethod(){
  18.                
  19.                 System.out.println("父类的静态InheritMethod");
  20.         }
  21.         public static void sOverrideMethod(){
  22.         
  23.                 System.out.println("父类的Overrid静态方法");
  24.         }
  25.         
  26.         public static String tPrint(String str){
  27.                
  28.                 System.out.println(str);
  29.                 return str;
  30.         }
  31.         
  32.         
  33.         public void cInheritMethod(String str_2){
  34.                
  35.                 System.out.println(str_2);
  36.         }
  37.         
  38. }
  39. public class SubClass extends Parent {

  40.         public static String ssv = tPrint("子类的静态变量初始化了");
  41.         //public static SubClass sc_1 = new SubClass();//---------------(1)
  42.         //public static Parent sc_5 = new SubClass();// ----------------(5)
  43.         
  44.         public String sv = tPrint("子类的普通成员变量初始化了");
  45.         //public SubClass sc_2 = new SubClass();//------------------------(2)
  46.         //public Parent sc_4 = new SubClass();//---------------------------(4)
  47.         
  48.         static {
  49.         
  50.                 System.out.println("子类的静态初始化块初始化了");
  51.         }
  52.         {
  53.                 cInheritMethod("子类的初始化块初始化了");
  54.         }
  55.         public SubClass() {
  56.         
  57.                 cInheritMethod("子类的构造方法初始化了");
  58.         }
  59.         public static void sOverrideMethod(){
  60.         
  61.                 System.out.println("子类重写的静态override方法");
  62.         }
  63.         
  64.         public static void main(String[] args) {
  65.         
  66. //SubClass sc_3 = new SubClass();// ------------------(3)
  67.         }
  68.         
  69. }
复制代码
有继承关系的子类的初始化和对象创建问题:
(1)(2)(3)(4)(5)共5个句子中,哪几个可以同时去掉注释,程序编译、运行正常?其中,解开(2)(3)的注释,会出现死循环,谁能具体解释下?同时解开(1)(3),sc_1和sc_3所指向的对象,哪个最先完成创建?最好能从内存的角度描述子类初始化和创建对象过程中,类和对象中各个成员所属内存的创建顺序、变动。

评分

参与人数 1技术分 +1 收起 理由
袁錦泰 + 1 回来我在研究你这个吧,现在看你这个有抵触.

查看全部评分

4 个回复

倒序浏览
本帖最后由 罗文杰 于 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:}
(以上是个人见解,如有纰漏,望请指正,谢谢~)











评分

参与人数 1技术分 +1 收起 理由
袁錦泰 + 1 很给力!

查看全部评分

回复 使用道具 举报
忘了加,同理(1)(5)和(2)(4)也不能共存。
回复 使用道具 举报
先占个楼,这个问题很有意思。
回复 使用道具 举报
好吧都占楼~ 我也前排占位!
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马