结论:
- 父类静态代码块,父类静态成员变量(同级,按代码顺序执行)
- 子类静态代码块,子类静态成员变量(同级,按代码顺序执行)
- 父类普通代码块,父类普通成员变量(同级,按代码顺序执行)
- 父类构造方法
- 子类普通代码块,子类普通成员变量(同级,按代码顺序执行)
- 子类构造方法
注意:
- 我们new一个对象A时,首先会先创建A类的父类B的实例对象,如果B类仍有父类C,会先创建父类C的对象,以此类推,是一个递归的创建过程;
- 静态内容只在第一次被JVM加载时执行一次,之后不再执行。
测试代码:
/**
* Java对象初始化顺序
* 父类
*
* @author yaobo
* @version 1.0
* @date 2019/12/21 23:49
*/
public class Father {
static {
MessageUtil.message(Father.class, "父类静态代码块1");
}
{
MessageUtil.message(Father.class, "父类普通代码块1");
}
public int v1 = MessageUtil.initVariable(Father.class, "父类成员变量");
{
MessageUtil.message(Father.class, "父类普通代码块2");
}
public static int v2 = MessageUtil.initVariable(Father.class, "父类静态成员变量");
static {
MessageUtil.message(Father.class, "父类静态代码块2");
}
public Father() {
MessageUtil.message(Father.class, "父类无参构造方法");
}
}
/**
* Java对象初始化顺序
* 子类
*
* @author yaobo
* @version 1.0
* @date 2019/12/21 23:58
*/
public class Child extends Father {
static {
MessageUtil.message(Child.class, "子类静态代码块1");
}
{
MessageUtil.message(Child.class, "子类普通代码块1");
}
public int v1 = MessageUtil.initVariable(Child.class, "子类成员变量");
{
MessageUtil.message(Child.class, "子类普通代码块2");
}
public static int v2 = MessageUtil.initVariable(Child.class, "子类静态成员变量");
static {
MessageUtil.message(Child.class, "子类静态代码块2");
}
public Child() {
MessageUtil.message(Child.class, "子类无参构造方法");
}
public static void main(String[] args) {
Child child = new Child();
// 结论:
// 父类静态代码块,父类静态成员变量 -> 子类静态代码块,子类静态成员变量 ->
// 父类普通代码块,父类普通成员变量 -> 父类构造方法 -> 子类普通代码块,子类普通成员变 量 -> 子类构造方法
}
}
/**
* 消息打印工具类
*
* @author yaobo
* @version 1.0
* @date 2019/12/22 0:09
*/
public class MessageUtil {
static void message(Class c, String ms) {
if ("Child".equals(c.getSimpleName())) {
System.out.print("--");
}
System.out.println(c.getSimpleName() + ms);
}
static int initVariable(Class c, String ms) {
message(c, ms);
return 1;
}
}
运行结果:
Father父类静态代码块1
Father父类静态成员变量
Father父类静态代码块2
--Child子类静态代码块1
--Child子类静态成员变量
--Child子类静态代码块2
Father父类普通代码块1
Father父类成员变量
Father父类普通代码块2
Father父类无参构造方法
--Child子类普通代码块1
--Child子类成员变量
--Child子类普通代码块2
--Child子类无参构造方法
号外:
/**
* 一道阿里面试题
*
* @author yaobo
* @version 1.0
* @date 2019/12/21 23:36
*/
public class Test {
public static int k = 0;
public static Test t1 = new Test("t1");
public static Test t2 = new Test("t2");
public static int i = print("i");
public static int n = 99;
private int a = 0;
public int j = print("j");
{
print("构造块");
}
static {
print("静态块");
}
public Test(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++i;
++n;
}
public static int print(String str) {
System.out.println((++k) + ":" + str + " i=" + i + " n=" + n);
++n;
return ++i;
}
public static void main(String[] args) {
Test t = new Test("init");
}
}
运行结果:
1:j i=0 n=0
2:构造块 i=1 n=1
3:t1 i=2 n=2
4:j i=3 n=3
5:构造块 i=4 n=4
6:t2 i=5 n=5
7:i i=6 n=6
8:静态块 i=7 n=99
9:j i=8 n=100
10:构造块 i=9 n=101
11:init i=10 n=102