Какие этапы компиляции находятся между исходным кодом (Source Code) и байт-кодом (Bytecode) в Java?

«Какие этапы компиляции находятся между исходным кодом (Source Code) и байт-кодом (Bytecode) в Java?» — вопрос из категории Java Core, который задают на 10% собеседований Java Разработчик. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Компилятор javac преобразует исходный код (.java) в байт-код (.class) через несколько этапов:

  1. Лексический анализ (Lexical Analysis / Scanning): Исходный текст разбивается на токены (ключевые слова, идентификаторы, операторы, литералы).

    • Вход: int sum = a + b;
    • Выход: [int, sum, =, a, +, b, ;]
  2. Синтаксический анализ (Parsing): Поток токенов преобразуется в Абстрактное Синтаксическое Дерево (AST), отражающее грамматическую структуру программы.

    • AST для int sum = a + b; будет иметь корень VariableDeclaration, с детьми type(int), name(sum) и выражение BinaryExpression(+) с операндами a и b.
  3. Семантический анализ (Semantic Analysis): Проверка корректности программы согласно правилам языка.

    • Проверка типов: Соответствуют ли типы в выражениях?
    • Разрешение символов: Существует ли объявленная переменная a?
    • Проверка доступности: Видна ли переменная в данной области видимости?
  4. Генерация и оптимизация байт-кода: AST преобразуется в инструкции виртуальной машины Java (JVM). Выполняются простые оптимизации (например, свертка констант).

Пример:

// Исходный код (Source Code)
public class Demo {
    public static void main(String[] args) {
        int result = 10 + 20;
        System.out.println(result);
    }
}

После javac Demo.java этапы 1-4 преобразуют этот код в файл Demo.class, содержащий байт-код (инструкции типа bipush, iadd, invokevirtual).