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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李玉江 中级黑马   /  2013-6-1 18:42  /  1640 人查看  /  2 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

同学提出的问题   不知道为什么是这种情况  求高手解释
class StaticCode
{
                  
           private static StaticCode tt = new StaticCode();
           static
            {
                           //6
                 System.out.println("StaticCode类的静态代码块");
               
            }
          private InstanceCode In = new InstanceCode();

          private StaticCode()
          {
                          //5
                          
                 System.out.println("StaticCode类的构造函数");
          }

           {
                           //4
                 System.out.println("StaticCode类的构造代码块");
           }
                  public static void main(String[] args){
                 
                  }
        
}


class InstanceCode
{
           static
          {
                           //1
                System.out.println("Instance类的静态代码块");
          }

                  
           {
                           //2
                System.out.println("Instance类的构造代码块");
           }
          InstanceCode()
          {
                          //3
                System.out.println("Instance类的构造函数");
          }
}



/*
执行后结果为什么是:
Instance类的静态代码块
Instance类的构造代码块
Instance类的构造函数

StaticCode类的构造代码块
StaticCode类的构造函数
StaticCode类的静态代码块   
*/

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

2 个回复

倒序浏览
本帖最后由 xiatian 于 2013-6-1 21:23 编辑

首先创建一个新对象,最先找到的是这个对象的构造代码块,构造函数,最后是它的静态方法。
接着回到你这个程序。
类的加载顺序是 先加载静态语句,静态语句执行的是创建了一个new StaticCode()的新对象。所以重新回到StaticCode类中,找这个类成员变量也就是 private InstanceCode In 它被赋予了一个新对象 new InstanceCode();所以就跳到InstanceCode类中,InstanceCode中没有静态执行语句,也没有执行语句 ,所以执行的顺序就是 静态代码块,构造代码块,构造函数。结束以后就运行了StaticCode自己的构造代码块,构造函数,最后是它自己的静态方法。
这么说不知道你能不能理解。

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
本帖最后由 阿里策 于 2013-9-26 21:35 编辑

    创建对象时执行顺序应该是这样的(Car c = new Car;):(1)加载类,(2)执行类的静态成员变量和成员方法, (3)开辟对象的内存空间,(4)默认初始化对象的成员变量 (5)显示初始化对象的成员变量(如 int a = 2;这种成员变量赋值语句) (6)构造代码初始化对象的成员变量 (7)构造函数初始化对象的成员变量 (8)将对象的堆内存地址赋值给栈内存中的引用变量c;  并且这个过程中静态成员只执行一次。
    对于该题,首先加载类,然后执行{1}静态成员变量private static StaticCode tt = new StaticCode(); 然后再执行{2}静态代码块 static{System.out.println("StaticCode类的静态代码块");}。这里执行{1}时,生成一个StaticCode的对象,按理说应该先加载StaticCode类,再执行静态成员变量和方法,但是类前面已经加载过了,静态成员变量前面也已经执行过了,所以不需要重复,接着就是执行默认初始化对象的成员变量,赋值为空。然后执行显示初始化对象的成员变量private InstanceCode In = new InstanceCode(); 这又创建一个对象,按照上述顺序就会出现InstanceCode的静态代码块,InstanceCode的构造代码块,InstanceCode的构造函数。接着执行构造代码块初始化,打印StaticCode类的构造代码块;构造函数初始化,打印StaticCode类的构造函数;然后才执行{2}打印StaticCode类的静态代码块。接下来本该执行第一段中的(4)(5)(6)(7)步骤,但是这些在执行{1}时就已经执行过了,而且他们这些初始化动作只执行一次,所以不会重复执行。    你这个例子正好印证了我的另一个关于类加载执行顺序的答案!
    但是我同时还有一个疑问:在执行{1}时,我觉得应该先执行StaticCode类的静态代码段的,就是应该第一个打印StaticCode类的静态代码块。但是实际的运行时却不是,而是跳过了,不知道怎么回事。。

回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马