Прежде чем писать код, полезно понять, чем этот код собирается и запускается. В Java вокруг самого языка есть небольшой набор инструментов, без которых ничего не заработает. Разберём их по порядку — от того, что вы ставите на машину, до сборщиков, которые тянут зависимости за вас.
JDK, JRE и JVM — кто есть кто
Три буквы, которые путают чаще всего. Разберёмся, что внутри.
JVM (Java Virtual Machine) — виртуальная машина. Это программа, которая исполняет скомпилированный Java-код. Вы пишете .java, компилятор превращает его в байт-код (.class), а JVM этот байт-код выполняет. Именно JVM даёт знаменитое «написал один раз — запускается везде»: байт-код одинаковый, а под каждую операционную систему есть своя JVM.
JRE (Java Runtime Environment) — среда выполнения. Это JVM плюс стандартные библиотеки (коллекции, работа с файлами, сетью и т. д.). Этого набора достаточно, чтобы запускать готовые Java-программы, но не хватает, чтобы их компилировать.
JDK (Java Development Kit) — комплект разработчика. Это JRE плюс инструменты разработки: компилятор javac, отладчик и прочее. Для разработки вам нужен именно JDK.
Короткая формула: JDK = JRE + инструменты разработки, JRE = JVM + библиотеки.
На практике сегодня отдельный JRE почти не ставят — скачивают JDK (например, сборку Temurin, Liberica или Amazon Corretto) и работают с ним.
Компиляция и запуск вручную
Чтобы прочувствовать, что происходит под капотом сборщиков, один раз стоит собрать программу руками.
Пусть есть файл Hello.java:
public class Hello {
public static void main(String[] args) {
System.out.println("Привет, Java!");
}
}
Компилируем компилятором javac — он создаёт Hello.class с байт-кодом:
javac Hello.java
Запускаем командой java (имя класса, без расширения .class):
java Hello
В Java 21 простой случай можно запустить вообще без отдельной компиляции — java Hello.java скомпилирует и запустит в один шаг. Это удобно для экспериментов, но реальные проекты всё равно собирают полноценно.
classpath — где искать классы
Как только классов становится больше одного и появляются чужие библиотеки, JVM нужно объяснить, где их искать. За это отвечает classpath — список папок и архивов, в которых лежат .class-файлы.
# запустить класс, указав, что искать классы надо в папке out и в библиотеке lib/some.jar
java -cp out:lib/some.jar Hello
Разделитель в classpath зависит от системы: двоеточие : в Linux и macOS, точка с запятой ; в Windows. Руками classpath собирают редко — обычно за вас это делает сборщик, и понимать это полезно в основном для диагностики ошибок вида ClassNotFoundException (класс не нашёлся в classpath).
Что такое jar
Раскидывать сотни .class-файлов неудобно. jar (Java ARchive) — это обычный zip-архив с .class-файлами и сопроводительными данными внутри. Один файл вместо россыпи классов: его удобно передавать, подключать как зависимость и запускать.
Если в jar прописана точка входа (главный класс), его можно запустить напрямую:
java -jar app.jar
Библиотеки, которые вы подключаете к проекту, тоже приезжают в виде jar-файлов. Ваш собственный проект на выходе сборки чаще всего тоже превращается в jar.
Maven и Gradle — зачем нужны сборщики
Пока проект — это один файл, javac и java хватает. Но реальное приложение состоит из десятков своих классов и зависит от чужих библиотек, у которых есть свои зависимости. Скачивать всё это руками, прописывать classpath и следить за версиями — мучительно. Эту работу берут на себя сборщики: они скачивают зависимости, компилируют код, прогоняют тесты и собирают итоговый jar.
В мире Java два основных сборщика — Maven и Gradle. Оба умеют одно и то же; различаются форматом описания проекта.
Координаты зависимости. Любая библиотека в Java однозначно описывается тремя частями: groupId (кто издал, обычно в стиле обратного домена), artifactId (что это за библиотека) и version (версия). Эта тройка — её координаты. По координатам сборщик находит и скачивает нужный jar из репозитория (по умолчанию — Maven Central).
Maven описывает проект в файле pom.xml (XML). Зависимость выглядит так:
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>33.2.1-jre</version>
</dependency>
Gradle описывает проект в build.gradle (Groovy) или build.gradle.kts (Kotlin). Та же зависимость — одной строкой по координатам:
dependencies {
implementation("com.google.guava:guava:33.2.1-jre")
}
Команда сборки тоже короткая: mvn package у Maven, gradle build у Gradle (или ./gradlew build через обёртку-wrapper, которая ставит нужную версию Gradle сама).
Базовая структура проекта
Maven и Gradle по умолчанию ожидают одинаковую раскладку папок — её придерживается почти весь экосистемный код:
my-app/
├── pom.xml # или build.gradle(.kts)
└── src/
├── main/
│ ├── java/ # исходный код приложения
│ └── resources/ # файлы-настройки, шаблоны и т. п.
└── test/
├── java/ # код тестов
└── resources/ # данные для тестов
Главное правило: рабочий код — в src/main, тесты — в src/test. Сборщик знает эти пути и не требует их настраивать. Результат сборки складывается в отдельную папку (target/ у Maven, build/ у Gradle), которую в систему контроля версий не коммитят.
Управление версией JDK
JDK выходит регулярно, и на одной машине часто нужно несколько версий: один проект на Java 17, другой на Java 21. Держать их и переключаться помогают менеджеры версий.
- SDKMAN! — популярный инструмент для Linux и macOS. Ставит и переключает JDK (и сам Gradle/Maven) одной командой:
sdk install java 21.0.3-tem, затемsdk use java 21.0.3-tem. - Версию по умолчанию задаёт переменная окружения
JAVA_VERSIONчерезJAVA_HOME— путь к нужному JDK. Командыjava -versionиjavac -versionпоказывают, какая версия активна сейчас.
Отдельно стоит знать про LTS-версии (Long-Term Support) — это выпуски с долгой поддержкой (17, 21, …). Для рабочих проектов обычно выбирают именно их: под них дольше выходят обновления безопасности.
Коротко
- JVM исполняет байт-код, JRE = JVM + библиотеки (только запуск), JDK = JRE + инструменты (для разработки нужен JDK).
javac Hello.javaкомпилирует исходник в байт-код.class,java Helloего запускает.- classpath — список путей, где JVM ищет классы; ошибка
ClassNotFoundExceptionозначает, что класс там не нашёлся. - jar — zip-архив с классами; готовое приложение запускают как
java -jar app.jar. - Maven (
pom.xml) и Gradle (build.gradle) скачивают зависимости по координатамgroupId:artifactId:versionи собирают проект. - Стандартная раскладка одинакова: код в
src/main/java, тесты вsrc/test/java. - Несколько версий JDK на машине удобно держать через SDKMAN!; для работы выбирают LTS-версии.
Что почитать дальше
- Синтаксис и типы данных — из чего состоит сам код, который вы компилируете.
- Исключения — как Java сообщает об ошибках во время выполнения.
- ООП в Java — классы, объекты и то, как из них строят программу.