Лекция 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-платформы
| Аббревиатура | Расшифровка | Назначение |
|---|---|---|
| JVM | Java Virtual Machine | Виртуальная машина, исполняющая байт-код |
| JRE | Java Runtime Environment | Среда выполнения: библиотеки классов, загрузчик, JVM |
| JDK | Java Development Kit | Средства разработки. Основной — OpenJDK |
Три части JVM
- Спецификация — набор правил, описывающий как должна быть реализована JVM. По сути сводится к «JVM должна правильно запускать программы, написанные на Java».
- Реализация — реальная программа, которая запускает Java-код. Существует много реализаций (как коммерческих, так и open-source).
- Экземпляр — оболочка над вашим кодом, которая его исполняет. Например, 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!");
}
}