🎓 УРОК 1: JDK и Hello World


📌 ЦЕЛИ УРОКА

К концу этого урока ты сможешь:

  1. Объяснить, что такое JDK, JRE и JVM, и как они связаны между собой
  2. Понять, почему Java — компилируемый + интерпретируемый язык (в отличие от Python)
  3. Написать, скомпилировать и запустить первую Java-программу через терминал и через IntelliJ IDEA
  4. Разобрать структуру простейшей Java-программы: class, main, System.out.println
  5. Понять принцип "Write Once, Run Anywhere" и роль байт-кода

📖 ТЕОРЕТИЧЕСКАЯ ЧАСТЬ

1. Компилируемый vs интерпретируемый язык

Python (интерпретируемый):

your_script.py  →  Python-интерпретатор читает построчно  →  выполнение

Ты запускаешь python script.py, и интерпретатор в реальном времени превращает каждую строку в машинные инструкции.

Java (компилируемо-интерпретируемый гибрид):

Main.java  →  [компиляция]  →  Main.class (байт-код)  →  [JVM интерпретирует/JIT-компилирует]  →  выполнение

Здесь два этапа:

  1. Компиляция — компилятор javac превращает твой человекочитаемый код .java в байт-код .class (это НЕ машинный код процессора, а промежуточный универсальный код).
  2. Выполнение — 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 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

public static void main(String[] args)

Это точка входа в программу — специальный метод, с которого JVM начинает выполнение. Разберём каждое слово:

⚠️ Эта строка — "магическое заклинание", которое нужно запомнить дословно. Пока не пытайся понять каждое слово досконально (static, модификаторы — будут отдельные уроки), просто зафиксируй: эта строка всегда одинакова для точки входа программы.

System.out.println("Hello, World!");

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!

Что происходит "под капотом":

  1. Файл Main.java компилируется командой javac Main.java → создаётся Main.class (байт-код)
  2. Команда java Main запускает JVM, которая загружает Main.class в память
  3. JVM ищет метод main с точной сигнатурой public static void main(String[] args) — если такого метода нет, будет ошибка Error: Main method not found
  4. JVM выполняет байт-код метода 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:


Пример 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 Когда использовать
Запустить программу Shift + F10 Ctrl + R Каждый раз после написания кода — проверить результат
Создать новый класс Alt + Insert (в папке проекта) Cmd + N Создание файла .java
Автоформатирование кода Ctrl + Alt + L Cmd + Alt + L Привести код к правильным отступам (аналог black в Python)
Автодополнение (базовое) Ctrl + Space Ctrl + Space Подсказка методов/переменных при наборе
Быстрый ввод sout → разворачивается в System.out.println() Tab после ввода sout Tab после sout Экономия времени — самая полезная "фишка" на старте!
Быстрый ввод psvm → разворачивается в public static void main Tab после psvm Tab после psvm Не набирать точку входа руками
Показать быструю документацию Ctrl + Q F1 Понять, что делает метод, не выходя из кода
Отменить/повторить действие Ctrl + Z / Ctrl + Shift + Z Cmd + Z / Cmd + Shift + Z Стандартные undo/redo
Найти файл в проекте Ctrl + Shift + N Cmd + Shift + O Быстрая навигация
Комментировать строку Ctrl + / Cmd + / Закомментировать код для отладки

💡 Совет: первым делом запомни 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");
    }

Что нужно сделать:

  1. Найти и перечислить все ошибки текстом (не только исправить, но и объяснить каждую)
  2. Предоставить исправленный рабочий код
  3. Запустить и приложить скриншот/вывод консоли

Критерии оценки: все 4 ошибки найдены и объяснены, код компилируется и запускается.

(Подсказка: ошибки касаются регистра имени класса/main, отсутствия ;, неверного синтаксиса вызова метода, отсутствия закрывающей скобки класса)


Задача 3: "Мини-калькулятор вывода" (комплексная)

Напиши программу, которая выводит в консоль:

  1. Результаты 4 арифметических операций (сложение, вычитание, умножение, деление) над числами 17 и 5, каждая с подписью
  2. Результат сравнения этих чисел (17 > 5)
  3. Строку, которая доказывает разницу между конкатенацией и сложением (покажи один пример с скобками и без)

Пример ожидаемого вывода:

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.


📚 ДОПОЛНИТЕЛЬНЫЕ МАТЕРИАЛЫ

Официальная документация:

На что обратить особое внимание:

Частые ошибки новичков:

  1. Забывают точку с запятой (особенно первые дни, пока рука не привыкла)
  2. Путают class Main и файл main.java (регистр не совпадает)
  3. Пытаются писать код вне класса, "как в Python"
  4. Путают print и println, забывая, что print не переносит строку
  5. Не понимают разницы между конкатенацией строк (+ со строкой) и арифметическим сложением — забывают скобки

✅ ЧЕК-ЛИСТ ГОТОВНОСТИ

После этого урока ты должен уметь без подсказок:

Если хотя бы один пункт вызывает сомнение — вернись к соответствующему разделу теории перед переходом к Уроку 2! 🚀