[转]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) {
}
}
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
{
}