JDK, JRE и JVM: как компилятор превращает Java-код в программу
Автор: Казачкин Даниил Михайлович · Обновлено
JDK нужен, чтобы писать и собирать Java-программы, а JVM выполняет их байткод. JRE обозначает среду выполнения: виртуальную машину вместе с библиотеками и необходимыми файлами. Эти названия описывают разные обязанности, поэтому установка «какой-нибудь Java» ещё не гарантирует наличие компилятора.
Три имени и одна программа
| Понятие | За что отвечает | Что искать при работе |
|---|---|---|
| JDK — Java Development Kit | Разработка, компиляция, запуск и диагностика | Компилятор javac, команда java, инструменты вроде javap |
| JRE — Java Runtime Environment | Выполнение готовой программы | JVM, стандартная библиотека и остальные компоненты runtime |
| JVM — Java Virtual Machine | Загрузка, проверка и выполнение байткода | Конкретная реализация виртуальной машины внутри runtime |
Это полезное разделение ролей, но не обязательная схема из трёх отдельных установщиков. Современный JDK уже позволяет запускать программы. У Oracle для современных выпусков нет отдельной привычной поставки JRE, а другие поставщики могут выпускать собственные runtime-пакеты. Начинающему разработчику для этого трека достаточно полного JDK. Пояснение dev.java.
Примеры рассчитаны на Java 25 LTS, без preview-возможностей. Это сознательно выбранная основа трека, а не утверждение, что более новых Java не существует. LTS описывает политику сопровождения поставщика; сроки и лицензии конкретной сборки проверяются отдельно. Дорожная карта Oracle.
От исходника до результата
Сохраните следующий собственный пример в файл FirstProgram.java в кодировке UTF-8:
public class FirstProgram {
public static void main(String[] args) {
int lessons = 10;
int minutesPerLesson = 35;
System.out.println("Study minutes: " + lessons * minutesPerLesson);
}
}В каталоге файла выполните:
javac -encoding UTF-8 --release 25 FirstProgram.java
java FirstProgramОжидаемый вывод — Study minutes: 350. Первая команда создаёт FirstProgram.class. Вторая получает имя класса без расширения .class. Компилятор проверяет синтаксис и типы, затем записывает байткод; запускающая команда находит класс и передаёт выполнение JVM. Параметр --release 25 фиксирует целевой выпуск языка, платформенных API и class-файлов. Справочник javac.
В примере class задаёт класс, фигурные скобки ограничивают его тело, main служит точкой входа. int — целочисленный тип, а System.out.println печатает строку. Пока важно увидеть два самостоятельных этапа. Подробно классы и значения разбираются в третьем уроке.
Почему байткод переносим, а runtime нужно выбирать
Один class-файл можно запускать на разных системах, если там есть совместимая JVM и необходимые зависимости. Сам JDK при этом собирается под конкретные ОС и архитектуру. Windows-архив нельзя просто использовать как Linux-runtime. Нативные библиотеки приложения также могут ограничивать переносимость.
JVM — абстрактная машина со своим форматом команд; реализация HotSpot может интерпретировать байткод и компилировать часто исполняемые участки в машинный код. Поэтому фраза «Java только интерпретируется» слишком груба, как и обещание, что javac сразу создаёт обычный исполняемый файл под процессор. Устройство JVM в спецификации, компиляция в HotSpot.
Как различить ошибку сборки и ошибку запуска
Измените int lessons = 10 на int lessons = "ten". javac сообщит об несовместимых типах: это ошибка исходника до выполнения. Не запускайте старый .class после неудачной сборки, иначе увидите прежний результат и решите, что исправления игнорируются.
Если компиляция успешна, но java пишет Could not find or load main class, проверяйте рабочий каталог, имя класса и classpath. UnsupportedClassVersionError означает несовместимость версии class-файла и запускающей JVM: сверяйте обе версии, а не только установленный JDK. Режимы запуска java.
Небольшой эксперимент с компилятором
Сначала получите исходный вывод. Затем замените число уроков на 12, пересоберите файл и убедитесь, что результат стал 420. После этого внесите ошибку типа и наблюдайте, какая команда перестала завершаться успешно. Запишите отдельно путь к исходнику, путь к class-файлу, версию javac и версию java: эти четыре факта помогут диагностировать чужой проект без догадок.
Проверка понимания: на другой компьютер перенесли только .java, а там доступна исключительно среда запуска без компилятора. Этого недостаточно для обычной отдельной сборки. Возможность source-file запуска не превращает любой урезанный runtime в полный комплект инструментов разработчика.
Частые вопросы
Нужно ли устанавливать JDK, JRE и JVM по очереди?
Для занятий установите один подходящий JDK. Он содержит инструменты разработки и компоненты выполнения. Отдельный runtime может понадобиться для развёртывания конкретного приложения, но три независимые установки для первого примера не требуются.
Почему java FirstProgram.java тоже работает?
Современный launcher поддерживает запуск исходного файла с компиляцией в рамках этой команды. В уроке этапы разделены намеренно: так видно, где возникает ошибка и какой артефакт получает следующий шаг.