Лекция 1

01.01.0001

Лекция 1. Вводная лекция: Java и JVM

О чём курс

Курс охватывает следующие темы:

  • Устройство виртуальной машины Java
  • Типы данных и ООП на Java
  • Обработка ошибок, Generics
  • Java коллекции и функциональное программирование
  • Работа с базами данных
  • Средства сборки и тестирование
  • Spring и микросервисы

Историческая справка: предпосылки появления Java

Эволюция языков программирования

40-е годы — перфокарты. Суперкомпьютер того времени мог принимать на ввод около 125 карт/минуту и выдавать 100 карт/минуту на вывод.

60-е годы. Появляются FORTRAN, BASIC, COBOL, Pascal, Ассемблер. Зарождаются основные парадигмы программирования. Разбиение на множество концепций (ПП, СП, ООП, ФП). Главный недостаток того времени — ни один язык не удовлетворял одновременно критериям:

  • простота использования
  • предоставляемые возможности
  • безопасность
  • эффективность
  • устойчивость
  • расширяемость

70-е годы. Появляется Си — современный этап развития языков. Удовлетворял всем критериям и был создан программистами для программистов (в отличие от академических или бюрократических предшественников).

80-е годы — период консолидации. Появляется C++, объединивший черты объектно-ориентированного и системного программирования. ООП решает проблему размера программ, разбивая их на классы и модули.

90-е годы. Массовая домашняя компьютеризация. Появляются требования к переносимости — возможности запуска одного и того же кода на различных платформах.

Рождение Java

Из «хотелки» переносимости родилась Java — язык, который теоретически мог бы запуститься на любом холодильнике, микроволновке или мобильном телефоне. Одновременно росла всемирная паутина, и вопрос платформонезависимости стал ещё острее.

В результате появился ЯП, который позволял запускать единожды скомпилированную программу на любой системной архитектуре и соответствовал высоким стандартам C++ (хотя в некоторых аспектах уступал ему).

Managed vs Unmanaged Code

Высокоуровневые языки обычно компилируют код не в машинный, а в промежуточный язык. Этот код потом подаётся в финальный компилятор, который создаёт объектный модуль или машинный код. Делается это для облегчения оптимизации и увеличения портируемости.

Байт-код и JVM

Байт-код Java — набор инструкций, исполняемых виртуальной машиной Java. Каждый код операции — один байт; из 256 возможных значений используются не все (51 зарезервирован для будущего).

Знание байт-кода не обязательно для программирования на Java, но понимание его генерации помогает Java-программисту так же, как знание ассемблера помогает C/C++-программисту.

Три кита Java-платформы

АббревиатураРасшифровкаНазначение
JVMJava Virtual MachineВиртуальная машина, исполняющая байт-код
JREJava Runtime EnvironmentСреда выполнения: библиотеки классов, загрузчик, JVM
JDKJava Development KitСредства разработки. Основной — OpenJDK

Три части JVM

  1. Спецификация — набор правил, описывающий как должна быть реализована JVM. По сути сводится к «JVM должна правильно запускать программы, написанные на Java».
  2. Реализация — реальная программа, которая запускает Java-код. Существует много реализаций (как коммерческих, так и open-source).
  3. Экземпляр — оболочка над вашим кодом, которая его исполняет. Например, Minecraft — это программа на Java, но запускается она в экземпляре JVM со своими ресурсами.

Пример: Java-код и его байт-код

Java-код:

package ru.butenko.springdatatest;
import java.time.LocalDate;

public class Dog {
    public String name;
    private LocalDate birthdate;

    public int calculateAge() {
        return LocalDate.now().getYear() - this.birthdate.getYear();
    }
}

Соответствующий байт-код:

public class ru/butenko/springdatatest/Dog {
  public Ljava/lang/String; name
  private Ljava/time/LocalDate; birthdate

  public calculateAge()I
    INVOKESTATIC java/time/LocalDate.now ()Ljava/time/LocalDate;
    INVOKEVIRTUAL java/time/LocalDate.getYear ()I
    ALOAD 0
    GETFIELD ru/butenko/springdatatest/Dog.birthdate
    INVOKEVIRTUAL java/time/LocalDate.getYear ()I
    ISUB
    IRETURN
}

Основы синтаксиса Java

Типы данных, операции, управляющие конструкции

  • Целочисленные: byte, short, int, long
  • С плавающей точкой: float, double
  • Логический: boolean
  • Символьный: char
  • Объекты и массивы: Object, int[] x

Поддерживаются: арифметические и логические операции, операции отношения, if/switch, while/do-while/for.

Синтаксис классов

Наследование:

public class Dog extends Animal {
    // код класса
}

Имплементация интерфейса:

public class Cat implements Eatable {
    // код класса
}

Исключения

Важно понимать ключевое различие:

  • Проверка на checked-исключения происходит в момент компиляции (compile-time checking).
  • Перехват исключений (catch) происходит в момент выполнения (runtime checking).
public class App {
    // "пугаем" компилятор тем, что можем выбросить Exception
    public static void main(String[] args) throws Exception {
        throw new Exception();
    }
}

JavaDoc

JavaDoc — встроенный инструмент документирования. Поддерживает теги @param, @return, @throws и другие.

/**
 * Класс, описывающий объект "Собака".
 */
public class Dog {
    public String name;
    private LocalDate birthdate;

    /**
     * Метод, который вычисляет возраст собаки на основе её даты рождения.
     *
     * @return int возраст собаки.
     */
    public int calculateAge() {
        return LocalDate.now().getYear() - this.birthdate.getYear();
    }

    /**
     * Метод, который задаёт кличку собаки.
     *
     * @param name - кличка, которая будет дана собаке.
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * Метод, который выбрасывает исключение.
     *
     * @throws Exception - базовое исключение для демонстрации тега.
     */
    public void doException() throws Exception {
        throw new Exception("Exception!");
    }
}