考虑以下代码:
public class Main {
static String s = "-";
public static void main (String [] args){
go();
System.out.println(s);
Main m = new Main();
}
{go();}
static {go();}
static void go(){s+="s";}
}
它的输出是:
-ss
从不调用实例init块,为什么?
答案 0 :(得分:5)
在您打印s
之后,它被称为。创建实例时会调用实例初始值设定项。
答案 1 :(得分:1)
它被称为。但是,在调用println之后调用它,因为您创建了Main的第一个实例。如果你将println的调用移到main的末尾,你会看到三个。
答案 2 :(得分:1)
实例初始化块代码在构造函数中调用super()之后运行,换句话说,在所有超级构造函数运行之后运行。
初始化块在类中出现的顺序很重要。如果一个类有多个,它们都按照它们出现在类文件中的顺序运行。
要记住的一些规则:
答案 3 :(得分:0)
它被调用,但是在您打印到控制台之后。在打印之前,你不会制作它的实例。
答案 4 :(得分:0)
正如其他人所指出的那样,实例init块被调用,但它不会影响System.out.println
语句的输出,因为它是与类实例的调用一起调用的:{{ 1}}
尝试调试这些情况时,您可以做的一件事是在调用点转储线程堆栈:
Main m = new Main();
这样,您就可以查看调用static void go() {
new Exception().printStackTrace(System.out);
s += "s";
}
方法的所有时间,并且在go
方法中使用与println
相同的打印流,您可以看到与main
var。
在我的版本中,结果如下所示:
s