public class TestInitialize {
public static void main(String args[]) {
System.out.println(B.value);
}
}
class A {
static int value = 100;
static {
System.out.println("A static block execute.");
}
}
class B extends A {
static {
System.out.println("B static block execute.");
}
public B() {
System.out.println("B constructor execute.");
}
}
public class TestInitialize {
public static void main(String args[]) {
new B();
}
}
class A {
static int value = 100;
/*
* 注意,在初始化的过程中,静态代码块和静态域的出现顺序很重要,虚拟机会严格按照在源代码中的出现顺序来执行初始化操作。
* 同样,对于成员变量和普通代码块也是一样的。
*/
static {
System.out.println("print static value in static block. static value:" + value);
System.out.println("A static block1 execute.");
}
static {
System.out.println("A static block2 execute.");
}
public int a;
{
System.out.println("A common block execute.");
}
public A() {
System.out.println("A constructor execute.");
}
}
class B extends A {
static {
System.out.println("B static block execute.");
}
{
System.out.println("B common block execute.");
}
public B() {
System.out.println("B constructor execute.");
}
}
输出结果如下:
print static value in static block. static value:100
A static block1 execute.
A static block2 execute.
B static block execute.
A common block execute.
A constructor execute.
B common block execute.
B constructor execute.
今天在看书时,碰到了这么一个问题。有如下这么一段代码:
本以为输出的结果中至少会有
B static block execute.
这么一段。后来执行后发现,结果如下:原来当访问一个java类或接口中的静态域时,只有真正声明这个域的类或接口才会被初始化。由于value是A类中的属性,B继承A。B.value直接访问的是类A中声明的静态域value。所以JVM只会初始化A.
既然看到这里,那就总结一下
Java
对象中各成员的初始化顺序。 1.父类静态成员和静态初始化块,按在代码中出现的顺序依次执行。 2.子类静态成员和静态初始化块,按在代码中出现的顺序依次执行。 3.父类实例成员和实例初始化块,按在代码中出现的顺序依次执行。 4.执行父类的构造方法。 5.子类实例成员和实例初始化块,按在代码中出现的顺序依次执行。 6.执行子类的构选方法。代码验证
输出结果如下:
代码很容易懂,这里就不解释了。