[转]Java中静态代码块及对象的初始化顺序

from:http://lehsyh.javaeye.com/blog/569674

修正了原文的一点错误

class Parent {
    static String name = "hello";
    static {
        System.out.println("parent static block");
    }
    {
        System.out.println("parent block");
    }

    public Parent() {
        System.out.println("parent constructor");
    }
}

class Child extends Parent {
    static String childName = "hello";
    static {
        System.out.println("child static block");
    }
    {
        System.out.println("child block");
    }

    public Child() {
        System.out.println("child constructor");
    }
}

 

public class StaticIniBlockOrderTest {     

  public static void main(String[] args) {     

  • new Child();//语句(*)   
  •   }     

     

    Q:当执行完语句(*)时,打印结果是什么顺序?为什么?
    A:当执行完语句(*)时,打印结果是这样一个顺序:parent static block,child static block,parent  block,parent constructor,child  block,child constructor。

    对象的初始化顺序:

    父类Static->子类static->父类缺省{}->父类构造函数->子类缺省{}->子类构造函数

    首先执行父类静态的内容,父类静态的内容执行完毕后,接着去执行子类的静态的内容,当子类的静态内容执行完毕之后,再去看父类有没有非静态代码块,如果有就执行父类的非静态代码块,父类的非静态代码块执行完毕,接着执行父类的构造方法;父类的构造方法执行完毕之后,它接着去看子类有没有非静态代码块,如果有就执行子类的非静态代码块。子类的非静态代码块执行完毕再去执行子类的构造方法。

    总之一句话,静态代码块内容先执行,接着执行父类非静态代码块和构造方法,然后执行子类非静态代码块和构造方法。
    注意:子类的构造方法,不管这个构造方法带不带参数,默认的它都会先去寻找父类的不带参数的构造方法。如果父类没有不带参数的构造方法,那么子类必须用super关键子来调用父类带参数的构造方法,否则编译不能通过。

    PS:

    1)、在静态方法里只能直接调用同类中其他的静态成员(包括变量和方法),而不能直接访问类中的非静态成员。
    2)、静态变量是属于整个类的变量而不是属于某个对象的。注意不能把方法体内的任何变量声明为静态。
    3)、当类被载入时,静态代码块被执行,且only被执行一次,静态块常用来执行类属性的初始化。例如:
    static
    {
    }

    posted @ 2010-10-16 05:41  irischan  阅读(863)  评论(0编辑  收藏  举报