Создание объекта статическим способом
может ли кто-нибудь объяснить, как 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
5 ответов:
- начинается инициализация класса. Изначально,
foo
null иsFlag
ложь- первый инициализатор статической переменной (
foo
) работает:
- новый экземпляр
Foo
создана- инициализатор переменной экземпляра для
flag
выполняется - в настоящее времяsFlag
false, таким образом, значениеflag
ложь- инициализатор второй статической переменной (
sFlag
) выполняется, значение правда- инициализация класса завершена
main
работает, печатьfoo.flag
, которое является ложнымобратите внимание, что если
sFlag
были признаныfinal
это будет рассматриваться как константа времени компиляции, в этот момент все ссылки на него будут в основном встроены вtrue
, так чтоfoo.flag
было бы верно тоже.
foo
создается во время статической инициализации класса и до инициализации sFlag, а значение по умолчанию логического значения равно false.
- класс загружен
Foo инициализируется в экземпляр
2.a флаг элемента экземпляра инициализируется значением sFlag (
false
по умолчанию)- sFlag инициализируется правда
пожалуйста, обратитесь к JLS §12.4 для более подробной информации.
когда класс загружается,
sFlag
иfoo
поля инициализируются, ноfoo
инициализируется первым!
поляflag
иsFlag
являются логическими и не могут быть нулевыми, поэтому по умолчанию есть false иsFlag
равно false, когдаfoo
инициализируется.flag = sFlag
после этогоflag
- Это ложь.Вот и все
общий порядок операций инициализации (после загрузки класса и перед первым использованием):
- статические (класс) блоки кода в порядке его появления в коде,
- блоки объектного кода в порядке их появления в коде (блоки инициализации и назначения).
- конструкторы
конечно, я не ссылаюсь на конструкторы и функции тела как блок кода выше .
Я не знаю, как о
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."); } }
приведенный выше код snipset печатает:
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.
сначала статические поля должны работать и сначала встроенные! так что на первой линии 4 и затем 5 будет работать так фу инициализируется первый и, как мы знаем, что логические переменные инициализируются в значение false по умолчанию, сначала так как переменная foo инициализируется области флаг sflag, которое ложно и тогда sfalsg становится правда, что не изменит флаг( нет связи), то, наконец, главное работает и печать фалг, что это ложь!!! Я надеюсь быть полезным! Будьте успешны