Когда вызываются блоки инициализации экземпляра? - PullRequest
2 голосов
/ 24 августа 2009

Рассмотрим этот код:

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 ]

5 голосов
/ 24 августа 2009

Это называется - ПОСЛЕ того, как вы напечатали s. Инициализаторы экземпляров вызываются при создании экземпляров.

1 голос
/ 03 марта 2013

Блочный код инициализации экземпляра запускается сразу после вызова super () в конструкторе, другими словами, после запуска всех суперконструкторов.

Порядок, в котором блоки инициализации появляются в классе, имеет значение. Если у класса есть несколько классов, все они запускаются в том порядке, в котором они указаны в файле класса.

Некоторые правила, которые нужно запомнить:

  1. Элемент списка Блоки инициализации выполняются в порядке их появления.
  2. Статические блоки инициализации запускаются один раз, когда класс первый загружены.
  3. Блоки инициализации экземпляра запускаются каждый раз, когда класс экземпляр создан.
  4. Блоки инициализации экземпляра запускаются после вызов конструктора для super ().
1 голос
/ 24 августа 2009

Это называется. Однако он вызывается после вызова println, потому что вы создаете первый экземпляр Main этого. Если переместить вызов println в конец main, вы увидите три с.

0 голосов
/ 24 августа 2009

Как указали другие, вызывается блок init экземпляра, но он не влияет на вывод вашего оператора System.out.println, потому что он вызывается вместе с вызовом экземпляра вашего класса: Main m = new Main();

Одна вещь, которую вы могли бы сделать при попытке отладки этих случаев, - сбросить стек потоков в точке вызова:

static void go() {
    new Exception().printStackTrace(System.out);
        s += "s";
}

Это позволит вам видеть, сколько раз вызывается метод go, и, используя тот же поток печати, что и ваш println в вашем методе main, вы можете видеть стеки относительно вывода вашего s вар.

В моей версии результат выглядит так:

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)
0 голосов
/ 24 августа 2009

Называется, но после печати на консоль. Вы не создаете его экземпляр до окончания печати. ​​

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...