我了解到初始化顺序的原则是:
但是我仍然对这段代码的输出感到困惑:
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
如果没有添加(10)的陈述;加(11);加(12);我完全可以理解。你能解释一下这三个陈述的初始化顺序吗?
答案 0 :(得分:7)
1)没有如下名称的块称为“实例初始化程序”,只有在创建新对象时才会调用它,如DefaultConstructor或noArg构造函数。
{
add(11);
}
2)在上面的代码中,您有静态阻止(首先在类加载时调用),实例初始化程序(创建对象时调用的内容),显式DefaultConstructor (在创建对象时调用,但始终记住Instance初始化程序优先级)和最后一个Main方法
3)现在让我们分析你的代码,
第一个电话:
static
{
add(2); //print 2
}
第二次致电:
static {
add(4); // print 4
}
第三次致电:
static {
new Test1();
// Here Object is getting created so all Instance Initialzer will be called first in a sequential manner.
}
第4次致电:
{
add(6); // print 6
}
第五次致电:
{
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
}
答案 1 :(得分:6)
静态初始化程序是第一个,所以你得到
2
4
但是在下一个静态初始化程序中,你调用了一个新的Test1.class实例,因此触发了实例初始化程序,在它们之后触发构造函数,然后得到:
6
8
11
5
Constructor!
之后调用其余的静态初始值设定项。这样:
12
最后一个是主要方法:
Main method!
10
答案 2 :(得分:1)
我觉得你很困惑因为(12)之前(主要方法 - 10)
发生这种情况是因为在最后但其他初始化顺序调用的main方法是明确的
答案 3 :(得分:1)
在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
答案 4 :(得分:1)
无论@DontPanic的答案是否正确,我要强调的要点是源代码中代码块的顺序(从上到下)也很重要,你可以看一下来自Java doc。{/ 3>的here
一个类可以有任意数量的静态初始化块,以及它们 可以出现在类体中的任何位置。运行时系统保证 静态初始化块按它们的顺序调用 出现在源代码中。