Ответ 1
Статический блок выполняется по порядку.
Сначала вы создаете объект Hello, на данный момент i = 0
, поскольку он не был установлен.
Только после этого i = 5
Вы должны прочитать статические инструкции сверху вниз.
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 инициализируются. объясните причину.
Статический блок выполняется по порядку.
Сначала вы создаете объект Hello, на данный момент i = 0
, поскольку он не был установлен.
Только после этого i = 5
Вы должны прочитать статические инструкции сверху вниз.
Нестатические переменные 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
.
Попробуйте поменять строки public static final Hello h = new Hello();
и static int i = 5;
.
Сначала вы инициализируете объект hello
(when i = 0, uninitialized)
и <<24 > . Сначала инициализируйте i
, чтобы получить ожидаемое поведение.
Вот что происходит в вашем первом примере:
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.Ответ Питера Лоури верен, ваше замешательство может исходить из того, что все находится в одном классе, и имена похожи на то, что я хотел дать вам другой способ визуализировать то, что вы делаете, поэтому ваш код логически эквивалентен следующий код:
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);
}
}
Java выполняет статическую инициализацию во время загрузки класса. Поэтому
public static final Hello h = new Hello();
создает объект с я = 5 и значением по умолчанию j, когда загружается класс Hello.
Если вы внесете как переменные i, так и j нестатические элементы, оба будут иметь значения по умолчанию для статического объекта h. p >
Если вы создаете новый объект в своем основном методе
Hello helloObj = new Hello();
Он даст вам нужный результат.
Из документов спецификаций оракула
Статический инициализатор, объявленный в классе, выполняется, когда класс инициализируется (§12.4.2). Вместе с инициализаторами полей для переменных класса (§8.3.2) статические инициализаторы могут использоваться для инициализации переменных класса класса.