Инициализация переменных экземпляра Java с помощью метода
Я немного запутался в следующем фрагменте кода:
public class Test{
int x = giveH();
int h = 29;
public int giveH(){
return h;
}
public static void main(String args[])
{
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
Результат здесь 0 29
, но я думал, что это должна быть ошибка компилятора, потому что переменная h не должна была инициализироваться, когда дело доходит до метода giveH()
. Итак, компиляция проходит через линии сверху вниз? Почему это работает? Почему значение x
0, а не 29?
Ответы
Ответ 1
Значение по умолчанию int
равно 0
(см. здесь). Поскольку вы инициализируете x
до h
, giveH
возвращает значение по умолчанию для int (например, 0).
Если вы измените порядок, подобный этому
int h = 29;
int x = giveH();
вывод будет
29 29
Ответ 2
Компиляция в Java не требует метода, который должен быть объявлен до его использования. Java-учебник более подробно описывает инициализацию.
Здесь можно подумать об этом: компилятор сделает заметку для поиска метода с именем giveH где-то в области видимости, и он будет только ошибкой, если он покинет область действия и не найдет ее. Как только он попадает в декларацию giveH, нота разрешается, и все довольны.
Кроме того, инициализация переменных для переменных экземпляра в Java перемещается в начало конструктора. Вы можете думать о том, что строки выше разделены на две части, с объявлением для x и h выше и присваиванием внутри конструктора.
Порядок объявления имеет значение в этом случае. Когда переменная x инициализируется, h имеет значение по умолчанию 0, поэтому giveH() вернет это значение по умолчанию. После этого переменной h присваивается значение 29.
Вы также можете посмотреть разделы спецификации Java Language Инициализация полей и Прямые ссылки во время инициализации поля.
Ответ 3
@Малобубола дал правильный ответ, но, поскольку вы, похоже, пока не понимаете, позвольте мне попытаться уточнить.
Когда Test создан, он запускает инициализацию переменной (x = giveH(), h = 29) один раз. Возможно, ваше недоразумение состоит в том, что переменная x всегда определяется выражениемH(), тогда как она определяет ее только при инициализации x.
Вот почему порядок высказываний здесь имеет решающее значение; x инициализируется до h, поэтому h равно 0, когда charH() вызывается при инициализации x.
Ответ 4
Плохая практика использования метода в инициализаторе поля. Вы можете исправить это, сделав h окончательным. Затем он будет инициализирован при загрузке класса.
import java.util.ArrayList;
public class Test {
int x = giveH();
final int h=29;
final public int giveH(){
return h;
}
public static void main(String args[]) {
Test t = new Test();
System.out.print(t.x + " ");
System.out.print(t.h);
}
}
Ответ 5
Если мы не инициализируем значение для нестатических переменных, таких как x в этой программе, JVM будет предоставлять значение по умолчанию для нестатических переменных уровня класса.