В многих традиционных языках программирования программы загружаются как часть запускающего процесса единожды. Затем происходит инициализация, а затем выполнение программы. В этих языках важно точно контролировать процесс инициализации, чтобы гарантировать, что инициализация static
данных не вызывает проблем. Например, если одно static
данные пытается использовать другое static
данные до его инициализации, это может привести к ошибкам в C++.
Java же такой проблемы не имеет благодаря своему подходу к загрузке. Поскольку все в Java являются объектами, многие процессы становятся проще, и этот вопрос — один из таких примеров. Как будет объяснено в следующей главе, код каждого объекта находится в отдельном файле. Этот файл загружается только тогда, когда действительно требуется его содержимое. Обычно можно считать, что код класса загружается только после того, как был создан хотя бы один экземпляр этого класса. Из-за некоторых нюансов с static
методами также можно сказать, что «код класса загружается при первом использовании».
Также стоит отметить, что в Java все объекты находятся в файлах, и эти файлы загружаются только при необходимости. Это позволяет избежать проблем инициализации static
данных, которые могут возникнуть в других языках программирования.Место первого использования также является местом инициализации static
. При загрузке все static
объекты и static
блоки кода инициализируются в том порядке, в котором они были указаны в определении класса (то есть в порядке их записи в коде класса). Разумеется, static
данные инициализируются только один раз.## 6.9.1 Наследование и инициализация
Нам следует иметь общее представление о процессе инициализации, особенно относительно наследования, чтобы понять происходящие события. Рассмотрим следующий код:
//: Жук.java
// Полный процесс инициализации.
class Насекомое {
int i = 9;
int j;
Насекомое() {
prt("i = " + i + ", j = " + j);
j = 39;
}
static int x1 =
prt("статическое Насекомое.x1 инициализировано");
static int prt(String s) {
System.out.println(s);
return 47;
}
}
public class Жук extends Насекомое {
int k = prt("Жук.k инициализировано");
Жук() {
prt("k = " + k);
prt("j = " + j);
}
static int x2 =
prt("статическое Жук.x2 инициализировано");
static int prt(String s) {
System.out.println(s);
return 63;
}
public static void main(String[] args) {
prt("конструктор Жук");
Жук b = new Жук();
}
} ///:~
Выходной поток программы выглядит так:
статическое Насекомое.x1 инициализировано
статическое Жук.x2 инициализировано
конструктор Жук
i = 9, j = 0
Жук.k инициализировано
k = 63
j = 39
При запуске java Жук
, первым делом происходит загрузка программы в JVM, которая находит указанный класс. В процессе загрузки загрузочный механизм замечает, что этот класс имеет базовый класс (то есть то, что указывает ключевое слово extends
), и последовательно загружает его. Этот процесс происходит независимо от того, создается ли объект этого базового класса (попробуйте закомментировать код создания объекта и проверьте это самостоятельно).Если базовый класс также имеет свой родительский класс, он тоже будет загружен последовательно. После этого выполняется статическая инициализация в корневом классе (в данном случае это Insect
), затем — в следующем производном классе и так далее. Это очень важно, поскольку инициализация производного класса может зависеть от правильной инициализации членов базового класса.
Когда все необходимые классы успешно загружены, можно создать объект. При этом все примитивные типы данных внутри объекта будут установлены по умолчанию, а ссылки на объекты — на null
. Затем вызывается конструктор базового класса. В данном случае вызов осуществляется автоматически, но можно явно указать вызов конструктора с помощью ключевого слова super
(как это сделано в первом действии конструктора Beetle
). Конструктор базового класса также проходит через тот же процесс инициализации, что и производный класс. После завершения инициализации конструктора базового класса, экземплярные переменные инициализируются в том порядке, в котором они были объявлены. Наконец, выполняется остальная часть конструктора.
Вы можете оставить комментарий после Вход в систему
Неприемлемый контент может быть отображен здесь и не будет показан на странице. Вы можете проверить и изменить его с помощью соответствующей функции редактирования.
Если вы подтверждаете, что содержание не содержит непристойной лексики/перенаправления на рекламу/насилия/вульгарной порнографии/нарушений/пиратства/ложного/незначительного или незаконного контента, связанного с национальными законами и предписаниями, вы можете нажать «Отправить» для подачи апелляции, и мы обработаем ее как можно скорее.
Опубликовать ( 0 )