Java 实例初始化块何时被调用?

Java 实例初始化块何时被调用?,java,Java,考虑以下代码: 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块从未被调用,为什

考虑以下代码:

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块从未被调用,为什么

打印完
s
后,将调用它。创建实例时会调用实例初始值设定项。

它会被调用。但是,它是在调用println之后调用的,因为您创建了它的Main的第一个实例。如果将对println的调用移动到main的末尾,您将看到三个s。

它被调用,但在您打印到控制台之后。直到打印之后,您才创建它的实例。

正如其他人所指出的,调用instance init块,但它不会影响
System.out.println
语句的输出,因为它是在调用类的实例时被调用的:
Main m=new Main()

尝试调试这些情况时可以做的一件事是在调用点转储线程堆栈:

static void go() {
    new Exception().printStackTrace(System.out);
        s += "s";
}
这将允许您查看调用
go
方法的所有时间,并且通过在
main
方法中使用与
println
相同的打印流,您可以查看与
s
var的输出相关的堆栈

在我的版本中,结果如下所示:

java.lang.Exception
    at Main.go(Main.java:29)
    at Main.<clinit>(Main.java:25)
java.lang.Exception
    at Main.go(Main.java:29)
    at Main.main(Main.java:14)
-ss
java.lang.Exception
    at Main.go(Main.java:29)
    at Main.<init>(Main.java:21)
    at Main.main(Main.java:17)
java.lang.Exception
at Main.go(Main.java:29)
在Main(Main.java:25)
java.lang.Exception
at Main.go(Main.java:29)
Main.Main(Main.java:14)
-党卫军
java.lang.Exception
at Main.go(Main.java:29)
在Main(Main.java:21)
Main.Main(Main.java:17)

实例初始化块代码在调用构造函数中的super()之后运行,换句话说,在所有超级构造函数运行之后

初始化块在类中出现的顺序很重要。如果一个类有多个类,它们都会按照它们在类文件中出现的顺序运行

要记住的一些规则:

  • 列表项初始化块按其出现的顺序执行
  • 静态初始化块在类第一次运行时运行一次 上膛了
  • 实例初始化块每次运行一个类时都会运行 实例被创建
  • 实例初始化块在 构造函数对super()的调用

  • 如果你们都想说同样的话,先投票给那个说同样话的人,然后再加上评论。将另一个“System.out.println(s);”添加到“main”块的末尾,您将看到“-sss”作为输出。