初始化顺序:父静态变量、父静态代码块、子类静态变量、子类静态代码块、父类非静态变量、父类非静态代码块、父类构造器、子类非静态变量、子类非静态代码块、子类构造函数。
执行顺序:父类B静态代码块->子类A静态代码块->父类B非静态代码块->父类B构造函数->子类A非静态代码块->子类A构造函数
例如:
class A {
public A() {
System.out.println("A的构造方法");
}
public static int j = print();
public static int print() {
System.out.println("A print");
return 521;
}
}
public class Test1 extends A {
public Test1() {
System.out.println("Test1的构造方法");
}
public static int k = print();
public static int print() {
System.out.println("Test print");
return 522;
}
public static void main(String[] args) {
System.out.println("main start");
Test1 t1 = new Test1();
}
}
输出结果为:
A print
Test print
main start
A的构造方法
Test1的构造方法
2. 类加载过程中,可能调用了实例化过程(因为static可以修饰方法,属性,代码块,内部类),此时则会暂停类加载过程而先执行实例化过程(被打断),执行结束再进行类加载过程,如下所示:【较难】
参考:https://www.cnblogs.com/greatfish/p/5771548.html
public class Text {
public static int k = 0;
public static Text t1 = new Text("t1");
public static Text t2 = new Text("t2");
public static int i = print("i");
public static int n = 99;
public int j = print("j");
{
print("构造块");
}
static {
print("静态块");
}
public Text(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[]) {
Text t = new Text("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
过程解读:首先会对静态变量进行初始化,对t1进行初始化时调用非静态方法,所以会被打断,先执行非静态变量的初始化,print(j),然后执行非静态代码块,最后才会执行对t1的初始化,同样,对于t2的初始化采取一样的操作,故而前六行的输出结果如上所示,然后对i进行初始化,调用静态方法,然后执行静态代码块的初始化,最后对非静态变量、非静态代码块进行初始化,最后执行main方法中的代码。
3. main方法中调用其他类中的方法执行顺序:参考:https://blog.youkuaiyun.com/exedllnet/article/details/51804202
public class Son{
Father father = new Father();
static{
System.out.println("Son static");
}
public Son(){
System.out.println("Son()");
}
}
public class Father {
static{
System.out.println("Father static");
}
public Father(){
System.out.println("Father()");
}
}
public class Main{
public static void main(String[] args){
Son son = new Son();
}
}
结果为:
Son static
Father static
Father()
Son()
过程解读:先执行static代码块,再初始化成员变量,再执行构造方法。
4.涉及子类与父类时的执行顺序:
public class Son extends Father{
//Father father = new Father();
static{
System.out.println("Son static");
}
public Son(){
System.out.println("Son()");
}
}
public class Father {
static{
System.out.println("Father static");
}
public Father(){
System.out.println("Father()");
}
}
public class Main{
public static void main(String[] args){
Son son = new Son();
}
}
运行结果如下:
Father static
Son static
Father()
Son()
过程解读:先执行父类的static代码块,再执行子类static,再执行构造方法。
5.多次创建对象,执行顺序:
public class Test_Static_Class {
//静态代码块
static {
System.out.println("静态代码块");
}
{
System.out.println("构造块1");
}
//构造方法
public Test_Static_Class() {
System.out.println("执行了构造方法");
}
//普通的成员方法
public void test() {
System.out.println("在方法中的普通代码块");
//普通的代码块
{
System.out.println("普通代码块");
}
}
public static void main(String[] args) {
System.out.println("执行了主方法");
System.out.println("--------------------");
new Test_Static_Class();
System.out.println("------第二次创建对象---------------");
new Test_Static_Class();
System.out.println("------第三次创建对象---------------");
new Test_Static_Class().test();
}
//构造块
{
System.out.println("构造块2");
}
}
运行结果:
过程解读:多次创建对象,静态代码块只执行一次,且最先执行。接下来执行的是构造快,构造块会每创建一个对象执行一次,且多个构造块会由上到下的执行。