黑马程序员技术交流社区

标题: 代码块执行顺序的问题 [打印本页]

作者: 李玉江    时间: 2013-6-1 18:42
标题: 代码块执行顺序的问题
同学提出的问题   不知道为什么是这种情况  求高手解释
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类的静态代码块   
*/
作者: xiatian    时间: 2013-6-1 21:01
本帖最后由 xiatian 于 2013-6-1 21:23 编辑

首先创建一个新对象,最先找到的是这个对象的构造代码块,构造函数,最后是它的静态方法。
接着回到你这个程序。
类的加载顺序是 先加载静态语句,静态语句执行的是创建了一个new StaticCode()的新对象。所以重新回到StaticCode类中,找这个类成员变量也就是 private InstanceCode In 它被赋予了一个新对象 new InstanceCode();所以就跳到InstanceCode类中,InstanceCode中没有静态执行语句,也没有执行语句 ,所以执行的顺序就是 静态代码块,构造代码块,构造函数。结束以后就运行了StaticCode自己的构造代码块,构造函数,最后是它自己的静态方法。
这么说不知道你能不能理解。
作者: 阿里策    时间: 2013-9-26 18:48
本帖最后由 阿里策 于 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类的静态代码块。但是实际的运行时却不是,而是跳过了,不知道怎么回事。。






欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2