1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/wizardforcel-thinking-in-java-zh

Присоединиться к Gitlife
Откройте для себя и примите участие в публичных проектах с открытым исходным кодом с участием более 10 миллионов разработчиков. Приватные репозитории также полностью бесплатны :)
Присоединиться бесплатно
В этом репозитории не указан файл с открытой лицензией (LICENSE). При использовании обратитесь к конкретному описанию проекта и его зависимостям в коде.
Клонировать/Скачать
6.9 初始化和类装载.md 7.1 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 11.03.2025 09:15 d56454c

6.9 Инициализация и загрузка классов

В многих традиционных языках программирования программы загружаются как часть запускающего процесса единожды. Затем происходит инициализация, а затем выполнение программы. В этих языках важно точно контролировать процесс инициализации, чтобы гарантировать, что инициализация 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 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/wizardforcel-thinking-in-java-zh.git
git@api.gitlife.ru:oschina-mirror/wizardforcel-thinking-in-java-zh.git
oschina-mirror
wizardforcel-thinking-in-java-zh
wizardforcel-thinking-in-java-zh
master