JavaRush /Курсы /Модуль 2. Java Core /Порядок загрузки классов

Порядок загрузки классов

Модуль 2. Java Core
8 уровень , 1 лекция
Открыта

— Привет, Амиго! Слышала, Риша рассказал тебе новую и очень интересную тему?!

— Да, Ким.

— Моя тема будет не менее интересной. Я хочу рассказать тебе о загрузке в память классов.

Классы в Java – это файлы на диске, содержащие байт-код – скомпилированный Java-код.

— Да, я помню.

— Java-машина не загружает их без необходимости. Как только где-то в коде происходит обращение к классу, Java-машина проверяет – загружен ли он. И если нет, то загружает и инициализирует его.

Инициализация класса – это присваивание значений всех его статических переменных и вызов всех статических блоков.

— Похоже на вызов конструктора у объекта. А что такое статический блок?

— Если для инициализации переменных объекта нужно выполнить сложный код (например, что-то загрузить из файла), мы можем сделать это в конструкторе. Статические переменные такой возможности лишены. Но т.к. потребность в этом осталась, в классы можно добавить статический блок или блоки, которые по сути своей эквивалентны вызову статических конструкторов.

Вот как это выглядит:

Код Что происходит на самом деле
class Cat
{
public static int catCount = 0 ;
public static String namePrefix;

static
{
Properties p = new Properties();
p.loadFromFile("cat.properties");
namePrefix = p.get("name-prefix");
}

public static int maxCatCount = 50;

static
{
Properties p = new Properties();
p.loadFromFile("max.properties");
if (p.get("cat-max") != null)
maxCatCount = p.getInt("cat-max");
}

}


class Cat
{
public static int catCount;
public static String namePrefix;
public static int maxCatCount;

//статические конструкторы в Java
//запрещены, но если бы они были, то все
//выглядело бы так
public static Cat()
{
catCount = 0;

Properties p = new Properties();
p.loadFromFile("cat.properties");
namePrefix = p.get("name-prefix");

maxCatCount = 50;

Properties p2 = new Properties();
p2.loadFromFile("max.properties");
if (p2.get("cat-max")!=null)
maxCatCount = p2.getInt("cat-max");
}
}

Это очень похоже на то, что происходит при вызове конструктора. Я даже записала это в виде несуществующего статического конструктора.

— Да, я все понял.

— Отлично.

Комментарии (6)
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ
Руслан Уровень 46
30 сентября 2025
🔹 Основные моменты Классы лежат на диске как .class и JVM не загружает их заранее. Класс загружается лениво — при первом обращении к нему: • создание объекта (new), • доступ к статическому полю или методу, • через Reflection. Инициализация класса выполняется один раз после загрузки: • всем static полям присваиваются значения по умолчанию (0, false, null), • выполняются присваивания при объявлении (static int x = 5;), • выполняются все static { … } блоки сверху вниз. Статические блоки позволяют выполнять сложную инициализацию для static полей (например, загрузка из файла), т.к. обычный конструктор к ним неприменим. Порядок важен: все static поля и блоки родителя инициализируются до потомка, чтобы потомки могли безопасно использовать их. JVM один раз инициализирует класс, статические поля и блоки повторно не выполняются. 🔹 Подводные камни • Значения по умолчанию присваиваются ещё до выполнения присваивания при объявлении и static-блоков. • Статические блоки выполняются в порядке появления в коде сверху вниз. • Попытка обратиться к static полю до инициализации класса триггерит его загрузку и инициализацию. • В Java нет статических конструкторов, но static-блоки инициализации работают аналогично. Вот может кому поможет
Ardan Уровень 57
11 марта 2025
Как я понял статические блоки это подготовка статических переменных класса к работе То есть когда JVM должен загрузить класс он внутри класса загружает статические переменные у которых есть статический блок для инициализации статической переменной и делается это всего раз за всю работу в классе отличай от сложной инициализации и простой

static int maxSpeed; //простая инициализаця
static{
    if(maxSpeed > 190){
        System.out.println("Вы почти достигли максимальной скорости"); //сложная инициализация
    }
}
Сложная инициализация нужна тогда когда то что нужно добавить в статическую переменную нельзя уместить в одну строку либо оно требует большей логики
Павел Уровень 19 Expert
12 октября 2023
Откуда взялся класс Properties? В Java есть такой в пакете java.base, но у этого класса не наблюдается метода loadFromFile() или get(). Амиго сказал "Да, я все понял". А понял он что его обманули?
Greg Уровень 108 Expert
4 октября 2022
Шото расплывчасто как-то....
Андраник Мамиконян Уровень 108 Expert
11 мая 2022
Название лекции и ее содержание, по-моему, отличаются