УРОК 1: JDK и Hello World
УРОК 1: JDK и Hello World
📌 ЦЕЛИ УРОКА
К концу этого урока ты сможешь:
Объяснить, что такое JDK, JRE и JVM, и как они связаны между собой
Понять, почему Java — компилируемый + интерпретируемый язык (в отличие от Python)
Написать, скомпилировать и запустить первую Java-программу через терминал и через IntelliJ IDEA
Разобрать структуру простейшей Java-программы:
class,main,System.out.printlnПонять принцип "Write Once, Run Anywhere" и роль байт-кода
СВЯЗЬ С ПРЕДЫДУЩИМИ ТЕМАМИ
Это первый урок, поэтому предыдущих тем по Java нет. Но у тебя есть опыт Python — будем от него отталкиваться.
Что ты уже знаешь из Python и что пригодится:
Ты понимаешь, что такое переменные, функции, консольный вывод (
print())Ты знаешь, что код можно запускать через терминал
Ты представляешь, что такое интерпретатор
Главное отличие, которое нужно сразу принять: В Python ты пишешь print("Hello") и сразу запускаешь файл — интерпретатор построчно читает и выполняет код. В Java так не работает. Java сначала компилируется в промежуточный байт-код, и только потом этот байт-код выполняется виртуальной машиной. Это фундаментальная разница в философии языков, и она объясняет 90% "странностей" синтаксиса Java, которые ты увидишь дальше.
📖 ТЕОРЕТИЧЕСКАЯ ЧАСТЬ
1. Компилируемый vs интерпретируемый язык
Python (интерпретируемый):
your_script.py → Python-интерпретатор читает построчно → выполнение
Ты запускаешь python script.py, и интерпретатор в реальном времени превращает каждую строку в машинные инструкции.
Java (компилируемо-интерпретируемый гибрид):
Main.java → [компиляция] → Main.class (байт-код) → [JVM интерпретирует/JIT-компилирует] → выполнение
Здесь два этапа:
Компиляция — компилятор
javacпревращает твой человекочитаемый код.javaв байт-код.class(это НЕ машинный код процессора, а промежуточный универсальный код).Выполнение — Java Virtual Machine (JVM) берёт этот байт-код и выполняет его, преобразуя "на лету" в машинные инструкции конкретной ОС/процессора (через JIT — Just-In-Time компилятор).
Почему так сделано? Философия Java — "Write Once, Run Anywhere" (WORA). Байт-код .class универсален: один и тот же скомпилированный файл будет работать на Windows, Linux, macOS — без пересборки. Меняется только JVM под конкретную систему, а твой код остаётся неизменным. В Python такой проблемы нет вообще (интерпретатор сам кросс-платформенный), но зато Python обычно медленнее в вычислительных задачах, а Java благодаря компиляции + JIT — значительно быстрее.
2. JDK, JRE, JVM — что это и в чём разница
Это самый частый источник путаницы у новичков. Разберём по слоям, как матрёшку:
┌──────────────────────────────────────────┐
│ JDK │ ← Java Development Kit
│ (нужен РАЗРАБОТЧИКУ для написания кода) │
│ ┌──────────────────────────────────┐ │
│ │ JRE │ │ ← Java Runtime Environment
│ │ (нужен для ЗАПУСКА программ) │ │
│ │ ┌────────────────────────┐ │ │
│ │ │ JVM │ │ │ ← Java Virtual Machine
│ │ │ (исполняет байт-код) │ │ │
│ │ └────────────────────────┘ │ │
│ │ + стандартные библиотеки │ │
│ └──────────────────────────────────┘ │
│ + компилятор javac │
│ + отладчик, javadoc, jar и др. утилиты │
└──────────────────────────────────────────┘
| Компонент | Что делает | Аналогия из Python |
|---|---|---|
JVM | Виртуальная машина, которая непосредственно выполняет байт-код | Сам интерпретатор python.exe |
JRE | JVM + стандартные библиотеки классов (нужно только чтобы ЗАПУСКАТЬ готовые программы) | Установленный Python + стандартная библиотека, но без pip/инструментов разработки |
JDK | JRE + инструменты разработчика (компилятор javac, отладчик jdb, документатор javadoc и т.д.) | Полная установка Python + pip + все dev-инструменты |
Важно понять: обычному пользователю, который просто запускает Java-приложение (например, Minecraft), достаточно JRE. Но тебе как разработчику нужен JDK, потому что только в нём есть компилятор javac, который превращает .java в .class.
⚠️ Начиная с Java 11, Oracle перестала распространять JRE отдельным пакетом — теперь обычно скачивают сразу JDK, даже если нужен только запуск программ. Это упростило жизнь, но важно знать историю термина, т.к. в статьях и видео 5-10-летней давности JRE упоминается как отдельный установочный пакет.
3. Версии Java: какую использовать
Java выпускает новые версии каждые полгода, но есть LTS-версии (Long-Term Support) — их поддерживают долго, и именно их используют в реальных проектах:
Java 8 — старый стандарт, до сих пор много legacy-проектов на нём
Java 11 — LTS
Java 17 — LTS, современный стандарт для новых проектов (рекомендую для обучения)
Java 21 — самая свежая LTS на момент написания
Для интенсива рекомендую Java 17 — она стабильна, поддерживает все современные фичи языка (var, records, switch expressions), и большинство обучающих материалов ориентированы на неё.
4. Структура простейшей Java-программы: разбор по кирпичикам
Вот минимальный код, который выведет "Hello, World!":
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
Сравним с Python:
print("Hello, World!")
Одна строка в Python превращается в 5 строк в Java. Почему? Потому что Java — строго объектно-ориентированный язык. В Java абсолютно весь код должен находиться внутри класса — ты не можешь просто написать команду "в воздухе", как в Python. Даже точка входа в программу — это метод внутри класса.
Разберём каждый элемент:
public class Main
class— ключевое слово, объявляющее класс (класс — это "чертёж" объекта, подробно разберём в уроке 14)Main— имя класса. Критически важно: имя класса должно точно совпадать с именем файла! Если класс называетсяMain, файл обязан называтьсяMain.java(с учётом регистра!). Это требование компилятора, а не просто соглашение — без этого код не скомпилируется.public— модификатор доступа, означает "класс виден отовсюду" (подробно разберём в уроке 28)
public static void main(String[] args)
Это точка входа в программу — специальный метод, с которого JVM начинает выполнение. Разберём каждое слово:
public— метод должен быть доступен JVM извнеstatic— метод принадлежит классу, а не конкретному объекту (объясним подробно в уроке 21). Пока запомни: JVM должна вызватьmain, не создавая объект класса, поэтому метод обязан бытьstaticvoid— метод ничего не возвращает (в Python аналог — функция безreturn, либоreturn None)main— зарезервированное имя метода, JVM ищет именно метод с таким именем и такой сигнатурой(String[] args)— параметр: массив строк, аргументы командной строки (аналогsys.argvв Python)
⚠️ Эта строка — "магическое заклинание", которое нужно запомнить дословно. Пока не пытайся понять каждое слово досконально (static, модификаторы — будут отдельные уроки), просто зафиксируй: эта строка всегда одинакова для точки входа программы.
System.out.println("Hello, World!");
System— встроенный класс Java, предоставляющий доступ к системным ресурсамout— статическое поле классаSystem, представляющее стандартный поток вывода (аналогsys.stdoutв Python)println— метод (сокращение от "print line"), выводит текст и переводит строку;— точка с запятой в конце КАЖДОГО оператора обязательна! Это первое серьёзное отличие от Python.
5. Точка с запятой и фигурные скобки — синтаксическая философия
В Python структура кода определяется отступами (indentation) — это часть синтаксиса:
if True:
print("да")
В Java структура кода определяется фигурными скобками { }, а отступы — это просто хороший тон (форматирование), не влияющий на работу программы:
if (true) {
System.out.println("да");
}
Ты технически можешь написать весь код Java в одну строку без единого отступа, и он скомпилируется. Но так делать нельзя — плохой код тяжело читать. IntelliJ IDEA автоматически форматирует код за тебя (об этом — в разделе горячих клавиш).
Точка с запятой ; завершает каждый оператор (выражение-действие). В Python перевод строки означает конец команды, в Java это делает ;. Забыть точку с запятой — самая частая ошибка новичков, компилятор сразу выдаст ошибку.
6. Комментарии в Java
// однострочный комментарий (как # в Python)
/*
многострочный
комментарий
*/
/**
* Javadoc-комментарий — специальный формат для документации класса/метода
* Используется генератором документации javadoc
*/
💻 ПРИМЕРЫ КОДА
Пример 1: Классический Hello World
public class Main { // 1. Объявляем публичный класс Main
public static void main(String[] args) { // 2. Точка входа в программу
System.out.println("Hello, World!"); // 3. Выводим строку с переносом строки
} // 4. Закрываем метод main
} // 5. Закрываем класс Main
Вывод в консоли:
Hello, World!
Что происходит "под капотом":
Файл
Main.javaкомпилируется командойjavac Main.java→ создаётсяMain.class(байт-код)Команда
java Mainзапускает JVM, которая загружаетMain.classв памятьJVM ищет метод
mainс точной сигнатуройpublic static void main(String[] args)— если такого метода нет, будет ошибкаError: Main method not foundJVM выполняет байт-код метода
mainпострочно
Пример 2: Несколько строк вывода + разница println/print
public class Main {
public static void main(String[] args) {
System.out.println("Первая строка"); // выводит текст + перенос строки
System.out.println("Вторая строка");
System.out.print("Без переноса "); // выводит БЕЗ перевода строки
System.out.print("строки");
}
}
Вывод в консоли:
Первая строка
Вторая строка
Без переноса строки
Аналогия с Python:
System.out.println(...)≈print(...)(Python по умолчанию добавляет\n)System.out.print(...)≈print(..., end="")в Python
Пример 3: Типичная ошибка — забыли точку с запятой
public class Main {
public static void main(String[] args) {
System.out.println("Hello, World!") // ❌ ОШИБКА! Нет точки с запятой
}
}
Что будет при компиляции:
error: ';' expected
System.out.println("Hello, World!")
^
1 error
⚠️ Как избежать: IntelliJ IDEA подчеркнёт эту строку красной волнистой линией ещё до компиляции. Всегда обращай внимание на подсказки IDE.
Пример 4: Ошибка несовпадения имени класса и файла
Если файл называется Main.java, но класс объявлен как:
public class HelloWorld { // ❌ имя класса ≠ имя файла
public static void main(String[] args) {
System.out.println("Привет!");
}
}
Ошибка компиляции:
error: class HelloWorld is public, should be declared in a file named HelloWorld.java
Как избежать: имя public-класса и имя файла ВСЕГДА должны совпадать (включая регистр!). Это правило только для public-классов — non-public класс может называться иначе, но в файле может быть только один public-класс.
Пример 5: Комбинированный вывод разных типов данных
public class Main {
public static void main(String[] args) {
// В памяти: JVM создаёт стек вызовов, main() попадает в Stack Frame
System.out.println("Java — компилируемый язык");
System.out.println("2 + 2 = " + (2 + 2)); // конкатенация строки и числа
System.out.println(10 > 5); // вывод boolean-значения
}
}
Вывод в консоли:
Java — компилируемый язык
2 + 2 = 4
true
Разбор памяти: когда JVM запускает main, она выделяет область стека (Stack) для этого метода. Каждая локальная переменная и вызов метода создают "фрейм" в стеке. Пока в этом примере нет переменных, но уже сейчас важно понимать: стек — быстрая память для примитивов и ссылок на объекты, куча (Heap) — память для самих объектов (детально разберём в уроке 3, когда дойдём до String и ссылочных типов).
⌨️ ГОРЯЧИЕ КЛАВИШИ INTELLIJ IDEA
| Действие | Windows/Linux | macOS | Когда использовать |
|---|---|---|---|
| Запустить программу |
|
| Каждый раз после написания кода — проверить результат |
| Создать новый класс |
|
| Создание файла .java |
| Автоформатирование кода |
|
| Привести код к правильным отступам (аналог black в Python) |
| Автодополнение (базовое) |
|
| Подсказка методов/переменных при наборе |
Быстрый ввод sout → разворачивается в System.out.println() |
|
| Экономия времени — самая полезная "фишка" на старте! |
Быстрый ввод psvm → разворачивается в public static void main |
|
| Не набирать точку входа руками |
| Показать быструю документацию |
|
| Понять, что делает метод, не выходя из кода |
| Отменить/повторить действие |
|
| Стандартные undo/redo |
| Найти файл в проекте |
|
| Быстрая навигация |
| Комментировать строку |
|
| Закомментировать код для отладки |
💡 Совет: первым делом запомни sout + Tab и Shift+F10 — этим будешь пользоваться постоянно на каждом уроке.
ПРАКТИЧЕСКИЕ ЗАДАНИЯ
Задание 1 (5 мин) — Классика
Напиши программу, которая выводит "Привет, Java!".
Критерий проверки: программа компилируется без ошибок, в консоли ровно одна строка Привет, Java!.
Задание 2 (5 мин) — Несколько строк
Выведи три строки: своё имя, возраст, и город — каждая на отдельной строке.
Пример вывода:
Меня зовут Алексей
Мне 25 лет
Я живу в Москве
Задание 3 (10 мин) — print vs println
Используя ТОЛЬКО System.out.print() (без println), выведи фразу "Java is fun!" так, чтобы она напечаталась одной строкой, собранной из трёх отдельных вызовов print().
Подсказка:
System.out.print("Java ");
System.out.print("is ");
System.out.print("fun!");
Критерий проверки: одна строка в выводе без лишних пробелов/переносов.
Задание 4 (10 мин) — Простая арифметика в выводе
Выведи результат выражения System.out.println("Результат: " + (15 + 27));
Затем попробуй убрать скобки вокруг 15 + 27 и посмотри, что изменится в выводе. Объясни своими словами, почему результат отличается.
Ожидаемый результат с скобками: Результат: 42 Без скобок: Результат: 1527 (произойдёт конкатенация строк, а не сложение — важный нюанс про приоритет операций!)
Задание 5 (10 мин) — Провокация ошибки
Специально убери точку с запятой в одной из строк и запусти компиляцию. Прочитай текст ошибки в консоли, найди номер строки, которую указывает компилятор, и исправь.
Цель: научиться читать сообщения об ошибках компилятора — это критичный навык на весь курс.
Задание 6 (15 мин) — ASCII-арт
Используя несколько System.out.println(), выведи простой ASCII-рисунок (например, треугольник из звёздочек):
*
**
***
****
Критерий проверки: визуально фигура выглядит правильно, каждая строка — отдельный println.
Задание 7 (15 мин) — Эксперимент с двумя классами в файле
Создай файл Main.java, объяви в нём два класса: public class Main и обычный (без public) class Helper. В Helper пока просто пустое тело {}. Скомпилируй файл и проверь: программа собирается без ошибок?
Цель: понять правило "один public-класс на файл, но non-public классов может быть несколько".
public class Main {
public static void main(String[] args) {
System.out.println("Main работает");
}
}
class Helper {
// пока пусто
}
Критерий проверки: компиляция прошла успешно, создалось ДВА файла .class: Main.class и Helper.class.
ПРОВЕРОЧНЫЕ ВОПРОСЫ
1. Что такое JVM?
ОтветJava Virtual Machine — виртуальная машина, которая выполняет байт-код (`.class` файлы), преобразуя его в машинные инструкции конкретной ОС/процессора.
2. В чём разница между JDK и JRE?
ОтветJRE = JVM + стандартные библиотеки (для ЗАПУСКА готовых программ). JDK = JRE + инструменты разработчика (компилятор javac и др.) — нужен для НАПИСАНИЯ и компиляции кода.
3. Что выведет этот код?
System.out.println("5 + 3 = " + 5 + 3);
Варианты: A) 5 + 3 = 8 Б) 5 + 3 = 53 В) Ошибка компиляции
Ответ**Б) `5 + 3 = 53`**. Оператор `+` выполняется слева направо. Сначала строка `"5 + 3 = "` конкатенируется с числом `5` → получается строка `"5 + 3 = 5"`. Затем к этой строке прибавляется `3` → снова конкатенация → `"5 + 3 = 53"`. Чтобы получить арифметический результат, нужны скобки: `"5 + 3 = " + (5 + 3)`.
4. Обязательно ли имя файла должно совпадать с именем класса?
ОтветДа, но только для **public**-класса. Если класс не публичный, совпадение не требуется.
5. Что произойдёт, если убрать точку с запятой после System.out.println("Hello")?
ОтветОшибка компиляции: `';' expected`. Код не скомпилируется, `.class` файл не будет создан.
6. Что выведет код?
System.out.print("A");
System.out.print("B");
System.out.println("C");
System.out.println("D");
Ответ``` ABC D ``` `print` не добавляет перенос строки, поэтому A, B, C выводятся подряд на одной строке. `println` после "C" добавляет перенос, поэтому "D" уже с новой строки.
7. Может ли метод main называться по-другому, например mainMethod?
ОтветНет. JVM ищет точку входа именно по сигнатуре `public static void main(String[] args)`. Если назвать иначе, JVM выдаст ошибку `Error: Main method not found`.
8. Что означает static в объявлении метода main (на базовом уровне)?
ОтветМетод принадлежит классу, а не конкретному объекту — JVM может вызвать его без создания экземпляра класса. (Подробный разбор — урок 21).
9. Сколько public-классов может быть в одном .java-файле?
ОтветРовно **один**. Остальные классы в этом файле должны быть без модификатора `public` (default-доступ).
10. Что такое байт-код и чем он отличается от машинного кода?
ОтветБайт-код — промежуточный универсальный код (`.class` файл), понятный JVM, но не процессору напрямую. Машинный код — набор инструкций конкретного процессора. JVM транслирует байт-код в машинный код во время выполнения (через интерпретацию или JIT-компиляцию).
11. В Python отступы влияют на работу кода. А в Java?
ОтветНет, в Java отступы — это просто визуальное форматирование для читаемости. Структуру кода определяют фигурные скобки `{ }`.
12. Что выведет код?
System.out.println(10 > 5);
Ответ`true` — результат логического сравнения, тип `boolean`.
13. Верно ли, что для запуска готовой Java-программы обязательно нужен именно JDK, а не JRE?
ОтветНет. Для **запуска** достаточно JRE (или входящей в JDK JVM). JDK нужен именно для **разработки** — компиляции своего кода. Однако начиная с Java 11, отдельного пакета JRE официально не распространяют, обычно ставят JDK целиком.
14. Что делает горячая клавиша sout + Tab в IntelliJ IDEA?
ОтветАвтоматически разворачивает сокращение в полную конструкцию `System.out.println();`, экономя время набора.
15. Почему в Java нельзя просто написать print("Hello") вне класса, как в Python?
ОтветJava — строго объектно-ориентированный язык, весь код обязан находиться внутри класса. Даже точка входа (`main`) — это метод класса, а не изолированная команда.
ДОМАШНЕЕ ЗАДАНИЕ
Задача 1: "Визитная карточка"
Напиши программу BusinessCard.java, которая выводит "визитку" в консоль в оформленном виде, используя минимум 6 вызовов println/print.
Пример вывода:
Иванов Алексей Java Developer (в обучении) Email: ivanov@example.com Телефон: +7 900 000-00-00
**Обязательные требования:**
- Имя класса `BusinessCard`, файл `BusinessCard.java`
- Минимум одна строка использует конкатенацию строк с числом (например, стаж: `"Опыт: " + 0 + " лет"`)
- Код должен иметь минимум 2 комментария (объясняющих секции)
---
### Задача 2: "Диагностика ошибок"
Ниже приведён "сломанный" код. Перепиши его правильно, найдя и исправив **все** ошибки (их там 4).
```java
public class main {
public static void Main(String[] args) {
System.out.println("Тест 1")
System.out.print.ln("Тест 2");
}
Что нужно сделать:
Найти и перечислить все ошибки текстом (не только исправить, но и объяснить каждую)
Предоставить исправленный рабочий код
Запустить и приложить скриншот/вывод консоли
Критерии оценки: все 4 ошибки найдены и объяснены, код компилируется и запускается.
(Подсказка: ошибки касаются регистра имени класса/main, отсутствия ;, неверного синтаксиса вызова метода, отсутствия закрывающей скобки класса)
Задача 3: "Мини-калькулятор вывода" (комплексная)
Напиши программу, которая выводит в консоль:
Результаты 4 арифметических операций (сложение, вычитание, умножение, деление) над числами
17и5, каждая с подписьюРезультат сравнения этих чисел (
17 > 5)Строку, которая доказывает разницу между конкатенацией и сложением (покажи один пример с скобками и без)
Пример ожидаемого вывода:
17 + 5 = 22
17 - 5 = 12
17 * 5 = 85
17 / 5 = 3
17 > 5: true
Конкатенация: 17 + 5 = 175
Сложение: 17 + 5 = 22
(Обрати внимание: 17 / 5 = 3, а не 3.4 — почему? Это подсказка к теме следующего урока про целочисленное деление, попробуй загуглить самостоятельно, если интересно)
Критерии оценки: все 6 строк выводятся корректно, использованы и println, и хотя бы один print.
📚 ДОПОЛНИТЕЛЬНЫЕ МАТЕРИАЛЫ
Официальная документация:
Oracle Java Documentation — официальный справочник по Java 17
Java Language Specification (JLS) — для глубокого понимания (не обязательно читать сейчас, но полезно знать, что существует)
На что обратить особое внимание:
Разница между
JDK/JRE/JVM— этот вопрос часто спрашивают на собеседованиях, важно уметь объяснить чёткоРегистр имён (
Main≠main) — Java чувствительна к регистру (case-sensitive), как и Python, но здесь это критичнее из-за требования совпадения имени класса и файла
Частые ошибки новичков:
Забывают точку с запятой (особенно первые дни, пока рука не привыкла)
Путают
class Mainи файлmain.java(регистр не совпадает)Пытаются писать код вне класса, "как в Python"
Путают
printиprintln, забывая, чтоprintне переносит строкуНе понимают разницы между конкатенацией строк (
+со строкой) и арифметическим сложением — забывают скобки