何时调用实例init块?

时间:2009-08-24 17:15:49

标签: 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块,为什么?

5 个答案:

答案 0 :(得分:5)

在您打印s之后,它被称为。创建实例时会调用实例初始值设定项。

答案 1 :(得分:1)

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

答案 2 :(得分:1)

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

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

要记住的一些规则:

  1. 列表项初始化块按它们出现的顺序执行。
  2. 静态初始化块在类首次运行时运行一次 加载。
  3. 实例初始化块每次运行一次 实例已创建。
  4. 实例初始化块在之后运行 构造函数调用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