Подтвердить что ты не робот

Поведение статической инициализации Java

public class Hello {
        public static final Hello h = new Hello();
        static int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

        }
        public static void main(String[] args) {

            h.print();
        }

    }

Этот вывод кода равен 5, 0. если причина статических нагрузок сначала в классе, а я инициализируется, а j - нет. Но если я удалю статику из я также

public class Hello {
        public static final Hello h = new Hello();
        int i = 5;
        int j  = i;

        private void print() {
            System.out.println(i+" , "+j);

        }
        public static void main(String[] args) {

            h.print();
        }

    }

теперь почему вывод 5,5. затем, когда я и j инициализируются. объясните причину.

4b9b3361

Ответ 1

Статический блок выполняется по порядку.

Сначала вы создаете объект Hello, на данный момент i = 0, поскольку он не был установлен.

Только после этого i = 5

Вы должны прочитать статические инструкции сверху вниз.

Ответ 2

Нестатические переменные i и j инициализируются в тот момент, когда создается объект Hello:

public static final Hello h = new Hello();

В первой части вопроса Peter вы дали ответ. Позвольте мне дополнить его. Если вы изменили порядок статических переменных:

static int i = 5;
public static final Hello h = new Hello();
int j  = i;

он напечатает 5, 5, а не 5, 0.

Ответ 3

Попробуйте поменять строки public static final Hello h = new Hello(); и static int i = 5;. Сначала вы инициализируете объект hello (when i = 0, uninitialized) и <<24 > . Сначала инициализируйте i, чтобы получить ожидаемое поведение.

Ответ 4

Вот что происходит в вашем первом примере:

  • Статическая память инициализируется на 0. В этот момент Hello.i равен 0.
  • Hello.h создается:
    • Hello.h.j инициализируется текущим значением Hello.i, то есть 0.
  • Hello.i инициализируется 5.

В вашем втором примере, с другой стороны:

  • Hello.h создается:
    • Hello.h.i инициализируется значением 5.
    • Hello.h.j инициализируется текущим значением Hello.h.i, т.е. 5.

Ответ 5

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

public class Program {

    public static Hello h = new Hello();

        public static void main(String [] args) {
            h.i = 5;
            h.print();
        }
    }

    class Hello {

        public static int i = 0;
        private int j = i;

        public void print() {
            System.out.println(i+", "+j);
        }
    }

Ответ 6

Java выполняет статическую инициализацию во время загрузки класса. Поэтому

public static final Hello h = new Hello();

создает объект с я = 5 и значением по умолчанию j, когда загружается класс Hello.

Если вы внесете как переменные i, так и j нестатические элементы, оба будут иметь значения по умолчанию для статического объекта h. p >

Если вы создаете новый объект в своем основном методе

Hello helloObj = new Hello();

Он даст вам нужный результат.

Ответ 7

Из документов спецификаций оракула

Статический инициализатор, объявленный в классе, выполняется, когда класс инициализируется (§12.4.2). Вместе с инициализаторами полей для переменных класса (§8.3.2) статические инициализаторы могут использоваться для инициализации переменных класса класса.