Создание объекта статическим способом

Может ли кто-нибудь объяснить, как Java выполняет этот код? Я имею в виду порядок выполнения каждого оператора.

public class Foo
{
    boolean flag = sFlag;
    static Foo foo = new Foo();
    static boolean sFlag = true;

    public static void main(String[] args)
    {
        System.out.println(foo.flag);
    }
}

ВЫВОД:

false

Ответ 1

  • Начальная инициализация класса. Первоначально foo имеет значение null, а sFlag - false
  • Первый инициализатор статической переменной (foo) запускается:
    • Создан новый экземпляр foo
    • Инициализатор переменной экземпляра для flag выполняется - в настоящее время sFlag имеет значение false, поэтому значение flag равно false
  • Выполняется второй инициализатор статической переменной (sFlag), устанавливая значение true
  • Инициализация классов завершена
  • main выполняется, распечатывается foo.flag, что неверно

Обратите внимание, что если sFlag объявлено как final, он будет рассматриваться как константа времени компиляции, после чего все ссылки на него будут в основном привязаны к true, поэтому foo.flag будет true тоже.

Ответ 2

foo создается во время статической инициализации класса и до того, как sFlag был инициализирован, а значение по умолчанию для логического значения - false.

  • Класс загружен
  • Foo инициализируется экземпляром

    2.a Флаг члена экземпляра инициализируется значением sFlag (false по умолчанию)

  • sFlag инициализируется значением true

Подробнее см. JLS §12.4.

Ответ 3

Когда класс загружен, поля sFlag и foo инициализируются, но сначала инициализируется foo!
поля flag и sFlag являются логическими и не могут быть нулевыми, поэтому по умолчанию есть false, а sFlag все еще ложно, когда инициализируется foo. flag = sFlag после этого flag является false.That это

Ответ 4

Общий порядок операций инициализации (после загрузки класса и перед первым использованием):

  • Статические (классные) блоки кода, чтобы они отображались в коде,
  • Блоки кода объекта, чтобы они отображались в коде (блоки инициализации и назначения).
  • Конструкторы

Конечно, я не ссылаюсь на конструкторы и функции как блок кода выше.

Я не знаю, как насчет полей final static. Похоже, что они следуют правилам полей static, и они не могут быть указаны перед объявлением, несмотря на предыдущие комментарии, которые они инициализируются на этапе компиляции. Если они ссылаются до возникновения ошибки компиляции:

Example.java:8: illegal forward reference
        System.err.println("1st static block j=" + j);

Может быть, поля final static могут быть инициализированы и скомпилированы в файл класса, но это не является общим правилом, и до объявления еще не могут быть указаны.

Пример кода для проверки порядка инициализации:

class Example {    

    final static int j = 5;

    {
        System.err.println("1st initializer j=" + j);
    }

    static {
        System.err.println("1st static block j=" + j);
    }

    static {
        System.err.println("2nd static block j=" + j);
    }

    final static java.math.BigInteger i = new java.math.BigInteger("1") {    
        {
            System.err.println("final static anonymous class initializer");
        }
    };

    Example() {
        System.err.println("Constructor");
    }

    static {
        System.err.println("3nd static block j=" + j);
    }

    {
        System.err.println("2nd initializer");
    }

    public static void main(String[] args) {
        System.err.println("The main beginning.");
        Example ex = new Example();
        System.err.println("The main end.");
    } 
}

Вышеприведенный снимок кода печати:

1st static block j=5
2nd static block j=5
final static anonymous class initializer
3nd static block j=5
The main beginning.
1st initializer j=5
2nd initializer
Constructor
The main end.

Ответ 5

сначала статические поля должны запускаться и сначала в линию! поэтому в первой строке 4 и затем 5 будет выполняться так, чтобы foo сначала инициализировался, и поскольку мы знаем, что логические переменные инициализируются по умолчанию по умолчанию, поэтому сначала, так как инициализируется foo, поле флага имеет значение sflag, что false, а затем sfalsg становится истинным, не изменит флаг (нет никакого отношения), тогда, наконец, основные запуски и фальц печати, который является ложным!!! Я надеюсь быть полезным! Будьте успешными