在Java中,main方法之后的那些语句的初始化顺序是什么
我了解到初始化顺序的原则是:
- 超类首先(在这种情况下不在这里讨论)
- 静态变量声明和静态初始化块按出现顺序排列
- 实例变量声明和静态初始化块按出现顺序排列
- 构造函数
但我仍然对此代码的输出感到困惑:
public class Test1 { static { add(2); } static void add (int num) { System.out.println(num + " "); } public Test1() { add(5); System.out.println("Constructor!"); } static { add(4); } { add(6); } static { new Test1(); } { add(8); } public static void main(String[] args) { System.out.println("Main method!"); add(10); } { add(11); } static { add(12); } }
结果是:
2 4 6 8 11 5 Constructor! 12 Main method! 10
如果没有add(10)的陈述; 加(11); 加(12); 我完全可以理解。 你能解释一下这3个语句的初始化顺序吗?
1)没有如下名称的块称为“ 实例初始化器 ”,只有在创建新对象时才会调用它,如DefaultConstructor或noArg构造函数。
{ add(11); }
2)在上面的代码中,你有静态块 ( 在类加载本身首先被调用 ), 实例初始化器 ( 在创建对象时被调用 ), 显式DefaultConstructor ( 在创建对象时被调用,但记住始终优先实例初始化器) )和最后的主要方法。
3)现在让我们分析你的代码,
第一次电话:
static { add(2); //print 2 }
第二个电话:
static { add(4); // print 4 }
第3个电话:
static { new Test1(); // Here Object is getting created so all Instance Initialzer will be called first in a sequential manner. }
第四个电话:
{ add(6); // print 6 }
第5个电话:
{ add(8); // print 8 }
第6次电话:
{ add(11); // print 11 }
第7次调用:在Instance Initializer之后,将调用Explicit Default Constructor。
public Test1() { add(5); // print 5 System.out.println("Constructor!"); // print Constructor! }
第8次调用:再次调用最后一个静态块。
static { add(12); // print 12 }
第9次调用:最后将调用main方法
public static void main(String[] args) { System.out.println("Main method!"); // print Main method! add(10); // print 10 }
静态初始化程序是第一个,所以你得到
2 4
但是在下一个静态初始化程序中,您调用Test1.class的新实例,因此触发实例初始化程序,在它们之后触发构造函数,并得到:
6 8 11 5 Constructor!
之后调用其余的静态初始化程序。 所以:
12
最后一个是主要方法:
Main method! 10
我觉得你很困惑,因为(12)之前(主要方法 – 10)
发生这种情况是因为在最后但是其他初始化顺序调用的main方法是明确的
在Java中,对于一个类, 所有静态初始化器在所有构造函数之前按顺序(从顶部到底部)执行。 {}中的术语被添加到构造函数中,这些不是静态初始化器(请参阅http://docs.oracle.com/javase/tutorial/java/javaOO/initial.html )。
那么Test1的实例1:
static { add(2); } ... static { add(4); }
然后,在静态块内部有一个Test1的构造函数。 它被调用,因此实例成员被初始化,因为之前的静态初始化器已被调用:
{ add(6); } ... { add(8); } ... { add(11); }
之后,调用构造函数中的下一个操作:
add(5);
然后我们在第一个实例中返回以调用最后一个静态initiazer:
static { add(12); }
最后,如果完全初始化了类,那么调用main方法:
public static void main(String[] args) { System.out.println("Main method!"); add(10); }
所以,输出:
2 4 6 8 11 5 Constructor! 12 Main method! 10
无论@DontPanic回答什么都是正确的,我要强调的要点是源代码中代码块的顺序(从上到下)也很重要 ,你可以从Java doc看这里 。
一个类可以有任意数量的静态初始化块,它们可以出现在类体中的任何位置。 运行时系统保证按照它们在源代码中出现的顺序调用静态初始化块。