Справочник по Java
Назначение
Справочник-шпаргалка по Java — типы, синтаксис, стандартная библиотека, типовые паттерны. Не заменяет пошаговое обучение. Учебный курс: раздел.
Учебные статьи: Типы данных и переменные · Коллекции (сводка операций).
Новые API-гайды раздела Java:
- Java Language Basics — полный API-гайд
- Collections Framework — полный API
- Stream API — полный API
- Stream Gatherers (Java 24+)
- Virtual Threads (Java 21+) — полный практический гайд
Краткое пояснение
Компоненты и ключевые особенности языка.
Быстрый старт
javac Main.java && java Main
mvn compile
mvn package
./gradlew build
java -jar app.jar
Справочные таблицы
Содержание справочника
- 1. Основные понятия и структура программы
- 2. Типы данных
- 3. Переменные
- 4. Операторы
- 5. Управляющие конструкции
- 6. Методы
- 7. Классы и объекты
- 8. Наследование и полиморфизм
- 9. Интерфейсы и абстрактные классы
- 10. Исключения (Exceptions)
- 11. Дженерики (Generics)
- 12. Коллекции (Collections Framework)
- 13. Многопоточность
- 14. Работа с файлами и вводом-выводом
- 15. Аннотации (Annotations)
- 16. Модульная система (Project Jigsaw, Java 9+)
- 17. Стандартная библиотека: ключевые пакеты
- 18. Дата и время (java.time)
- 19. Работа с JSON и XML
- 20. Сетевое программирование
- 21. JDBC (Java Database Connectivity)
- 22. Модульное тестирование
- 23. Сборка проектов
- 24. JVM: параметры запуска и настройка
- 25. Профилирование и мониторинг
- 26. Отладка
- 27. Лучшие практики разработки на Java
- 28. Language Basics — API-дополнение
- 29. Collections Framework — API-дополнение
- 30. Streams и Gatherers — API-дополнение
- 31. Virtual Threads — API-дополнение
- 32. Executor sizing heuristics
1. Основные понятия и структура программы
1.1. Класс
Каждая программа на Java начинается с определения класса. Класс — это шаблон для создания объектов, содержащий поля (переменные) и методы (функции).
public class MyClass {
// тело класса
}
1.2. Метод main
Точка входа в программу — метод main. Он должен быть статическим, иметь модификатор public, возвращать void и принимать массив строк в качестве аргумента.
public static void main(String[] args) {
// точка входа
}
1.3. Пакеты
Пакеты группируют связанные классы и интерфейсы. Объявление пакета — первая исполняемая строка в файле (кроме комментариев).
package com.example.myapp;
1.4. Импорты
Инструкции import подключают классы из других пакетов. Можно импортировать отдельные классы или все классы пакета с помощью звёздочки.
import java.util.List;
import java.util.*;
2. Типы данных
2.1. Примитивные типы
В Java восемь примитивных типов — от byte до boolean. Каждый имеет фиксированный размер, диапазон значений и назначение. Подробнее — Типы данных и переменные.
| Тип | Размер, байт | Диапазон значений | Назначение | Пример | По умолчанию |
|---|---|---|---|---|---|
byte | 1 | от −128 до 127 | целое число | byte b = -5; | 0 |
short | 2 | от −32 768 до 32 767 | целое число | short s = 42; | 0 |
int | 4 | от −2³¹ до 2³¹ − 1 | целое число | int i = -12345; | 0 |
long | 8 | от −2⁶³ до 2⁶³ − 1 | целое число | long l = 1_122_334_455L; | 0L |
float | 4 | ±1,4×10⁻⁴⁵ … ±3,4×10³⁸ | вещественное число | float f = 3.141592f; | 0.0f |
double | 8 | ±4,9×10⁻³²⁴ … ±1,8×10³⁰⁸ | вещественное число двойной точности | double d = 3.141592653589d; | 0.0d |
char | 2 | от 0 до 65 535 | символ (UTF-16) | char c = 'Z'; | '\u0000' |
boolean | не фиксирован | true или false | логическое значение | boolean b = true; | false |
Литералы float и long требуют суффиксов f/F и L/l. Целые литералы без суффикса — int; вещественные без суффикса — double.
2.2. Обёрточные классы (Wrapper Classes)
Каждому примитивному типу соответствует класс-обёртка:
ByteShortIntegerLongFloatDoubleCharacterBoolean
Эти классы позволяют использовать примитивы как объекты, поддерживают методы преобразования, сравнения и парсинга.
Пример:
Integer num = Integer.valueOf(42);
int primitive = num.intValue();
2.3. Ссылочные типы
Ссылочные типы включают:
- Классы (
String, пользовательские классы) - Интерфейсы
- Массивы
- Перечисления (
enum) - Аннотации
Значение ссылочного типа — это адрес объекта в куче. Значение по умолчанию — null.
3. Переменные
3.1. Объявление и инициализация
int age = 25;
String name = "Alice";
boolean isActive = true;
3.2. Область видимости
- Локальные переменные: объявлены внутри метода или блока. Должны быть инициализированы перед использованием.
- Поля класса (instance variables): принадлежат объекту. Инициализируются значениями по умолчанию.
- Статические поля (class variables): принадлежат классу. Объявляются с ключевым словом
static.
3.3. Модификаторы доступа для полей
public— доступ из любого местаprotected— доступ из того же пакета и подклассовdefault(без модификатора) — доступ только в пределах пакетаprivate— доступ только внутри класса
4. Операторы
4.1. Арифметические
+— сложение-— вычитание*— умножение/— деление%— остаток от деления
4.2. Унарные
+— унарный плюс-— унарный минус++— инкремент--— декремент!— логическое НЕ (дляboolean)
4.3. Операторы присваивания
=+=,-=,*=,/=,%=
4.4. Операторы сравнения
==— равенство (для примитивов — значение, для ссылок — адрес)!=— неравенство<,<=,>,>=
4.5. Логические операторы
&&— логическое И (с коротким замыканием)||— логическое ИЛИ (с коротким замыканием)&— побитовое И / логическое И без короткого замыкания|— побитовое ИЛИ / логическое ИЛИ без короткого замыкания^— исключающее ИЛИ (XOR)
4.6. Побитовые операторы
Побитовый оператор работает с отдельными битами целого (флаги, маски, сдвиги).
~— побитовое НЕ<<— сдвиг влево>>— арифметический сдвиг вправо>>>— логический сдвиг вправо
4.7. Тернарный оператор
int max = (a > b) ? a : b;
4.8. Оператор instanceof
Проверяет, является ли объект экземпляром указанного класса или интерфейса.
if (obj instanceof String) { ... }
5. Управляющие конструкции
5.1. Условные операторы
if-else
if (condition) {
// код
} else if (anotherCondition) {
// код
} else {
// код
}
switch (до Java 13 и после)
Поддерживает byte, short, char, int, String, enum, и начиная с Java 17 — sealed-классы.
Java 14+ поддерживает выражения switch:
int dayValue = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
5.2. Циклы
for
for (int i = 0; i < 10; i++) { ... }
for-each (enhanced for)
for (String item : list) { ... }
while
while (condition) { ... }
do-while
do {
// код
} while (condition);
5.3. Операторы управления потоком
break— выход из цикла или switchcontinue— переход к следующей итерации циклаreturn— выход из метода с возвратом значения (если метод неvoid)
Можно использовать метки для выхода из вложенных циклов:
outer: for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
if (someCondition) break outer;
}
}
6. Методы
Интерактивное демо — вызов функции и стек на примере JavaScript. В Java объявление другое, но вызов, локальные переменные и возврат устроены так же. Обобщённо: функции в коде.
Play ITЗагрузка интерактивного демо…
6.1. Сигнатура метода
[модификаторы] тип_возврата имя([параметры]) [throws исключения]
Пример:
public static int add(int a, int b) {
return a + b;
}
6.2. Перегрузка методов
Методы с одинаковым именем, но разными параметрами (тип, количество, порядок).
6.3. Вариадические методы
Принимают переменное число аргументов одного типа:
public void printAll(String... messages) {
for (String msg : messages) System.out.println(msg);
}
Вызов:
printAll("A", "B", "C");
6.4. Рекурсия
Метод вызывает сам себя. Должно быть условие завершения.
public int factorial(int n) {
if (n <= 1) return 1;
return n * factorial(n - 1);
}
7. Классы и объекты
7.1. Конструкторы
- Имя совпадает с именем класса
- Не имеют возвращаемого типа
- Вызываются при создании объекта через
new
public class Person {
private String name;
public Person(String name) {
this.name = name;
}
}
7.2. Ключевое слово this
Ссылается на текущий экземпляр объекта. Используется для:
- Разрешения конфликта имён (параметр и поле)
- Вызова другого конструктора (
this(...)) - Возврата текущего объекта
7.3. Статические члены
Объявляются с static. Принадлежат классу, а не экземпляру.
public static final double PI = 3.14159;
7.4. Блоки инициализации
- Статический блок: выполняется один раз при загрузке класса
- Блок инициализации экземпляра: выполняется перед каждым конструктором
static {
// инициализация статических полей
}
{
// инициализация полей экземпляра
}
8. Наследование и полиморфизм
8.1. Ключевое слово extends
Класс наследует поля и методы другого класса.
class Animal { ... }
class Dog extends Animal { ... }
8.2. Ключевое слово super
- Вызов конструктора родителя:
super(...) - Доступ к полям и методам родителя:
super.method()
8.3. Переопределение методов (Override)
Метод в подклассе заменяет метод родительского класса. Должен иметь:
- То же имя
- Те же параметры
- Совместимый тип возврата
- Уровень доступа не уже, чем у родителя
Аннотация @Override настоятельно рекомендуется: компилятор проверит, что метод действительно переопределяет родительский.
8.4. Запрет наследования
Класс, помеченный final, не может быть унаследован.
public final class MathUtils { ... }
9. Интерфейсы и абстрактные классы
9.1. Интерфейс (interface)
Интерфейс — это контракт, определяющий набор методов, которые должны быть реализованы классом. Начиная с Java 8, интерфейсы могут содержать:
- Абстрактные методы (без тела)
- Методы по умолчанию (
default) — с реализацией - Статические методы
- Частные методы (
private) — начиная с Java 9
public interface Drawable {
void draw(); // абстрактный метод
default void resize() {
System.out.println("Resizing...");
}
static boolean isSupported() {
return true;
}
}
Класс реализует интерфейс с помощью ключевого слова implements.
public class Circle implements Drawable {
public void draw() {
System.out.println("Drawing a circle");
}
}
Один класс может реализовывать несколько интерфейсов.
9.2. Абстрактный класс (abstract class)
Абстрактный класс — это класс, который не может быть инстанцирован напрямую и может содержать как абстрактные, так и конкретные методы.
public abstract class Shape {
protected String color;
public abstract double area();
public void setColor(String color) {
this.color = color;
}
}
Подкласс обязан реализовать все абстрактные методы, если сам не является абстрактным.
9.3. Отличия
- Интерфейс поддерживает множественное наследование поведения.
- Абстрактный класс позволяет наследовать состояние (поля) и частичную реализацию.
- Интерфейсы не имеют конструкторов; абстрактные классы — имеют.
10. Исключения (Exceptions)
10.1. Иерархия исключений
Throwable— корень иерархииError— фатальные ошибки (например,OutOfMemoryError)Exception- Проверяемые (checked) — компилятор требует обработки (
IOException,SQLException) - Непроверяемые (unchecked) — наследники
RuntimeException(NullPointerException,IllegalArgumentException)
- Проверяемые (checked) — компилятор требует обработки (
10.2. Обработка исключений
try {
// код, который может выбросить исключение
} catch (IOException e) {
// обработка
} finally {
// всегда выполняется
}
10.3. Множественные catch
catch (IOException | SQLException e) {
// обработка нескольких типов
}
10.4. Try-with-resources (Java 7+)
Автоматическое закрытие ресурсов, реализующих AutoCloseable.
try (FileInputStream fis = new FileInputStream("file.txt")) {
// работа с файлом
} // fis.close() вызывается автоматически
10.5. Создание собственных исключений
public class InvalidAgeException extends Exception {
public InvalidAgeException(String message) {
super(message);
}
}
11. Дженерики (Generics)
11.1. Основы
Дженерики обеспечивают типобезопасность при компиляции.
List<String> names = new ArrayList<>();
names.add("Alice");
// names.add(123); // ошибка компиляции
11.2. Параметры типа
T— TypeE— ElementK— KeyV— ValueN— Number
11.3. Ограничения
?— wildcard (неизвестный тип)? extends T— верхняя граница (любой подтип T)? super T— нижняя граница (любой надтип T)
Пример:
public void copy(List<? extends Number> src, List<? super Number> dest) { ... }
11.4. Стирание типов (Type Erasure)
Во время выполнения информация о дженериках недоступна. Это ограничивает рефлексию и запрещает создание массивов параметризованных типов.
12. Коллекции (Collections Framework)
12.1. Иерархия основных интерфейсов
CollectionList— упорядоченная коллекция с дубликатами (ArrayList,LinkedList,CopyOnWriteArrayList)Set— без дубликатов (HashSet,LinkedHashSet,TreeSet,EnumSet)Queue— очередь (ArrayDeque,PriorityQueue;BlockingQueue— вjava.util.concurrent)
Map— ассоциативный массив (HashMap,LinkedHashMap,TreeMap,ConcurrentHashMap)
Подробная шпаргалка с таблицами сложности — Коллекции в Java.
12.2. Основные реализации
| Тип | Особенности |
|---|---|
ArrayList | O(1) доступ по индексу; вставка в середину — O(n) |
LinkedList | O(1) вставка/удаление с известным узлом; get(i) — O(n) |
HashSet | Уникальность; O(1) в среднем; порядок не гарантирован |
LinkedHashSet | Как HashSet + порядок вставки |
TreeSet | Сортировка; O(log n) |
HashMap | Пары ключ–значение; O(1) в среднем; один null-ключ |
LinkedHashMap | Как HashMap + порядок вставки (или access-order) |
TreeMap | Сортировка по ключу; O(log n) |
ArrayDeque | Очередь и стек быстрее legacy Stack |
12.3. Утилиты
Collections—sort,reverse,shuffle,unmodifiableList,synchronizedListArrays— методы для массивов (asList,sort,binarySearch)
12.4. Stream API (Java 8+)
Подробнее: Stream API в Java.
Позволяет функционально обрабатывать коллекции.
List<String> result = names.stream()
.filter(n -> n.startsWith("A"))
.map(String::toUpperCase)
.collect(Collectors.toList());
13. Многопоточность
13.1. Создание потоков
- Через наследование
Thread - Через реализацию
Runnable - Через
ExecutorService
Thread t = new Thread(() -> {
System.out.println("Running in thread");
});
t.start();
13.2. Пул потоков
ExecutorService executor = Executors.newFixedThreadPool(4);
executor.submit(() -> { /* задача */ });
executor.shutdown();
13.3. Синхронизация
synchronized— блок или методvolatile— гарантирует видимость изменений между потокамиLock— гибкая альтернатива (ReentrantLock)AtomicInteger,AtomicReference— атомарные операции без блокировок
13.4. CompletableFuture (Java 8+)
Подробнее: Асинхронность в Java.
Асинхронное программирование с цепочками действий.
CompletableFuture.supplyAsync(() -> fetchData())
.thenApply(data -> process(data))
.thenAccept(result -> System.out.println(result));
13.5. JMM и concurrency decision table
| Ситуация | Базовый выбор |
|---|---|
| Флаг остановки, "готово/не готово" | volatile |
| Счетчик, инкремент, CAS | AtomicInteger / AtomicLong |
| Несколько полей должны меняться как единое состояние | synchronized или Lock |
| Много потоков читают редко изменяемую структуру | ReadWriteLock |
Короткое правило:
volatileрешает задачу видимости;x++остается неатомарной операцией;- для инкрементов и счетчиков лучше
AtomicIntegerилиAtomicLong.
14. Работа с файлами и вводом-выводом
Подробнее: Ввод-вывод и файлы в Java, Строки в Java.
14.1. Потоки ввода-вывода
InputStream/OutputStream— байтовыеReader/Writer— символьные
14.2. Файловые операции (NIO.2, Java 7+)
Пакет java.nio.file:
Path— путь к файлуFiles— статические методы (readAllLines,write,copy,delete)Paths.get("...")— создание объектаPath
Пример:
List<String> lines = Files.readAllLines(Paths.get("input.txt"));
Files.write(Paths.get("output.txt"), lines);
14.3. Сериализация
Класс должен реализовывать Serializable.
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("data.ser"));
oos.writeObject(obj);
15. Аннотации (Annotations)
Подробнее: Аннотации и рефлексия в Java, Современные конструкции Java.
15.1. Встроенные аннотации
@Override— переопределение метода@Deprecated— устаревший код@SuppressWarnings— подавление предупреждений
15.2. Создание собственных аннотаций
public @interface Author {
String name();
int version() default 1;
}
Использование:
@Author(name = "Timur", version = 2)
public class MyClass { ... }
15.3. Retention и Target
@Retention(RetentionPolicy.RUNTIME)— доступна во время выполнения@Target(ElementType.METHOD)— применима только к методам
16. Модульная система (Project Jigsaw, Java 9+)
16.1. module-info.java
module com.example.myapp {
requires java.base;
requires java.sql;
exports com.example.myapp.api;
}
16.2. Преимущества
- Явные зависимости
- Инкапсуляция пакетов
- Улучшенная производительность запуска
17. Стандартная библиотека — ключевые пакеты
| Пакет | Назначение |
|---|---|
java.lang | Основные классы (Object, String, Math, System) |
java.util | Коллекции, дата/время, Scanner, Random |
java.io | Потоки ввода-вывода |
java.nio | Новые I/O операции |
java.net | Сетевое взаимодействие |
java.time | Современный API даты и времени (Java 8+) |
java.text | Форматирование текста, чисел, дат |
java.math | BigInteger, BigDecimal |
java.security | Криптография, подписи |
javax.crypto | Шифрование |
18. Дата и время (java.time)
18.1. Основные классы
LocalDateTime— дата и время без часового поясаZonedDateTime— с часовым поясомInstant— момент времени в UTCDuration— временной промежуток в секундах/наносекундахPeriod— период в годах, месяцах, днях
18.2. Пример
LocalDateTime now = LocalDateTime.now();
LocalDateTime future = now.plusDays(7);
long days = ChronoUnit.DAYS.between(now, future);
19. Работа с JSON и XML
19.1. JSON
Java не включает встроенную поддержку JSON в стандартную библиотеку до Java EE / Jakarta EE, но широко используются сторонние библиотеки:
Jackson (наиболее популярная)
ObjectMapper mapper = new ObjectMapper();
String json = mapper.writeValueAsString(person);
Person p = mapper.readValue(json, Person.class);
Gson (от Google)
Gson gson = new Gson();
String json = gson.toJson(person);
Person p = gson.fromJson(json, Person.class);
19.2. XML
DOM-парсинг (в памяти)
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(new File("data.xml"));
SAX-парсинг (событийный, потоковый)
Подходит для больших файлов, потребляет меньше памяти.
JAXB (Java Architecture for XML Binding, устарел в Java 11, восстановлен в Jakarta EE)
Аннотации позволяют преобразовывать объекты в XML и обратно:
@XmlRootElement
public class Person {
@XmlElement
public String name;
}
20. Сетевое программирование
20.1. Низкоуровневые сокеты
TCP (Socket / ServerSocket)
// Сервер
ServerSocket server = new ServerSocket(8080);
Socket client = server.accept();
// Клиент
Socket socket = new Socket("localhost", 8080);
UDP (DatagramSocket)
DatagramSocket socket = new DatagramSocket();
byte[] buffer = "Hello".getBytes();
InetAddress address = InetAddress.getByName("localhost");
DatagramPacket packet = new DatagramPacket(buffer, buffer.length, address, 9000);
socket.send(packet);
20.2. HTTP-клиент (Java 11+)
Встроенная поддержка HTTP/2:
HttpClient client = HttpClient.newHttpClient();
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.example.com/data"))
.build();
HttpResponse<String> response = client.send(request, HttpResponse.BodyHandlers.ofString());
Для более сложных сценариев используются библиотеки: Apache HttpClient, OkHttp.
21. JDBC (Java Database Connectivity)
21.1. Подключение к базе
String url = "jdbc:postgresql://localhost:5432/mydb";
String user = "user";
String password = "pass";
Connection conn = DriverManager.getConnection(url, user, password);
21.2. Выполнение запросов
Statement (без параметров)
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM users");
PreparedStatement (с параметрами, защита от SQL-инъекций)
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
ps.setInt(1, userId);
ResultSet rs = ps.executeQuery();
21.3. Обработка результата
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
}
21.4. Транзакции
conn.setAutoCommit(false);
try {
// несколько операций
conn.commit();
} catch (SQLException e) {
conn.rollback();
}
21.5. Пулы соединений
Используются в production — HikariCP, Apache DBCP, C3P0.
22. Модульное тестирование
22.1. JUnit 5 (современный стандарт)
Аннотации
@Test— метод теста@BeforeEach,@AfterEach— перед/после каждого теста@BeforeAll,@AfterAll— статические методы, один раз на класс@Disabled— пропустить тест
Утверждения (Assertions)
assertEquals(expected, actual);
assertTrue(condition);
assertThrows(IllegalArgumentException.class, () -> method());
22.2. Mockito (моки)
List mockedList = Mockito.mock(List.class);
when(mockedList.get(0)).thenReturn("first");
assertEquals("first", mockedList.get(0));
verify(mockedList).get(0);
23. Сборка проектов
23.1. Maven
Файл pom.xml определяет проект, зависимости, плагины.
<dependencies>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.10.0</version>
<scope>test</scope>
</dependency>
</dependencies>
Команды Maven:
mvn compile
mvn test
mvn package
mvn clean install
23.2. Gradle
Файл build.gradle (Groovy или Kotlin DSL):
dependencies {
testImplementation 'org.junit.jupiter:junit-jupiter:5.10.0'
}
Команды:
./gradlew build
./gradlew build
./gradlew test
./gradlew test
./gradlew run
./gradlew run
Gradle использует инкрементальную сборку и кэширование, что ускоряет повторные сборки.
24. JVM — параметры запуска и настройка
Опции передаются команде java до имени класса или -jar. Они задают системные свойства, размер кучи, сборщик мусора, логирование GC и поведение при сбоях. Большинство флагов фиксируется при старте процесса; проверить фактическую конфигурацию работающей JVM можно через jcmd <pid> VM.flags (см. JVM в проде).
Теория памяти, поколений и алгоритмов GC — в JVM, память и потоки и сравнении GC Java, Python и Go.
24.1. Три категории флагов
HotSpot (OpenJDK) делит аргументы на три уровня. Префикс подсказывает, где искать опцию в справке.
| Категория | Префикс | Кто поддерживает | Как посмотреть список |
|---|---|---|---|
| Стандартные | без префикса (-D, -jar, …) | любая JVM по спецификации | java -help |
| Нестандартные | -X | реализация HotSpot (могут меняться между версиями) | java -X |
| Расширенные | -XX | тонкая настройка HotSpot | java -XX:+PrintFlagsFinal (длинный вывод) |
Синтаксис расширенных флагов: + включает булеву опцию, - выключает; для чисел и строк — -XX:Имя=значение (например -XX:MaxGCPauseMillis=200).
24.2. Стандартные опции
| Флаг | Назначение |
|---|---|
-Dproperty=value | Системное свойство; в коде — System.getProperty("property") |
-javaagent:/path/to/agent.jar | Подключение Java-агента (мониторинг, APM, bytecode-инструментация) |
-agentpath:pathname | Нативный агент по абсолютному пути |
-verbose:class | Лог загрузки каждого класса |
-verbose:gc | Краткий вывод событий GC (устаревает; предпочтителен -Xlog:gc* с JDK 9+) |
-verbose:jni | Вызовы JNI |
Пример:
java -Dfile.encoding=UTF-8 -Dspring.profiles.active=prod -jar app.jar
24.3. Нестандартные опции (-X)
| Флаг | Назначение |
|---|---|
-Xms<size> | Начальный размер heap (например 512m, 1g) |
-Xmx<size> | Максимальный размер heap; при исчерпании — OutOfMemoryError: Java heap space |
-Xss<size> | Размер стека одного потока (эквивалент -XX:ThreadStackSize) |
-Xint | Только интерпретация, без JIT (диагностика, не для продакшена) |
-Xbootclasspath:path | Дополнительные архивы для bootstrap class loader (редко) |
-Xloggc:file | Лог GC в файл (устарел; с JDK 9+ — -Xlog:gc*:file=gc.log) |
-Xnoclassgc | Отключить сборку неиспользуемых классов (узкие сценарии) |
-Xprof | Профилирование JVM (устарело; вместо него JFR, async-profiler) |
Типовый запуск с фиксированной кучей:
java -Xms1g -Xmx8g -jar app.jar
Равные -Xms и -Xmx убирают расширение heap во время работы и упрощают планирование памяти на сервере.
Metaspace (метаданные классов, с Java 8 вместо PermGen) настраивается флагами -XX, не -X:
-XX:MetaspaceSize— порог, после которого JVM запрашивает память у ОС-XX:MaxMetaspaceSize— жёсткий потолок (при превышении — OOM Metaspace)
24.4. Расширенные опции — поведение и GC
Выбор сборщика мусора (подробнее — раздел 4.15):
| Флаг | Сборщик | Когда уместен |
|---|---|---|
-XX:+UseSerialGC | Serial | Малый heap, одно ядро |
-XX:+UseParallelGC | Parallel (Throughput) | Пакетная обработка, допустимы редкие длинные паузы |
-XX:+UseG1GC | G1 | Универсальный выбор; по умолчанию с JDK 9 |
-XX:+UseZGC | ZGC | Низкие паузы, большие heap (JDK 15+ generational) |
-XX:+UseShenandoahGC | Shenandoah | Низкие паузы, альтернатива ZGC |
-XX:+UseConcMarkSweepGC | CMS | Удалён с JDK 14 — только legacy |
Параметры G1 и целевых пауз:
| Флаг | Назначение |
|---|---|
-XX:MaxGCPauseMillis=n | Целевая длительность паузы для G1 (ориентир, не гарантия) |
-XX:G1HeapRegionSize=4m | Размер региона G1 (обычно 1–32 МБ, часто подбирается автоматически) |
-XX:MaxNewSize=256m | Потолок young generation (для поколенческих сборщиков) |
Java Flight Recorder (JFR):
java -XX:+FlightRecorder -XX:StartFlightRecording=duration=60s,filename=app.jfr -jar app.jar
В Temurin/OpenJDK 11+ JFR доступен без коммерческой лицензии. Запись у работающего процесса — jcmd (см. JVM в проде — jcmd, дамп памяти и JFR).
Пример продакшен-профиля с G1:
java -Xms2g -Xmx2g -XX:+UseG1GC -XX:MaxGCPauseMillis=200 \
-Xlog:gc*,gc+heap=info:file=gc.log:time,uptime,level,tags \
-jar app.jar
24.5. Расширенные опции — отладка и диагностика
| Флаг | Назначение |
|---|---|
-XX:ErrorFile=./hs_err_%p.log | Файл при фатальной ошибке JVM (crash) |
-XX:+HeapDumpOnOutOfMemoryError | Автоматический heap dump при OOM |
-XX:HeapDumpPath=./dumps | Каталог для дампов |
-XX:OnError="cmd args" | Команда ОС при fatal error (осторожно в проде) |
-XX:+TraceClassLoading | Какие классы загружаются |
-XX:+PrintClassHistogram | Гистограмма объектов по SIGQUIT (Linux) / Ctrl+Break |
Логирование GC. Флаги -XX:+PrintGC, -XX:+PrintGCDetails устарели. С JDK 9 используйте унифицированное логирование:
-Xlog:gc*:file=gc.log:time,uptime,level,tags
Удалённая отладка (IDE подключается к процессу):
-agentlib:jdwp=transport=dt_socket,server=y,suspend=n,address=*:5005
suspend=y останавливает JVM до подключения отладчика — удобно при старте, опасно в проде без контроля.
24.6. Расширенные опции — производительность
| Флаг | Назначение |
|---|---|
-XX:ThreadStackSize=256 | Размер стека потока в килобайтах (аналог -Xss256k) |
-XX:+UseStringDeduplication | Дедупликация одинаковых String в G1 (JDK 8u20+) |
-XX:MaxPermSize=128m | Только Java 7 и ранее (PermGen); в Java 8+ — Metaspace |
-XX:+AggressiveOpts | Удалён; не использовать в новых версиях |
Модульная система (Java 9+): --add-opens java.base/java.lang=ALL-UNNAMED открывает пакет для reflection (часто в legacy-библиотеках и тестах). Это обход ограничений JPMS, а не замена явного opens в module-info.java.
24.7. Шпаргалка — что держать под рукой
| Задача | Минимальный набор флагов |
|---|---|
| Ограничить память | -Xms… -Xmx… |
| Включить G1 явно | -XX:+UseG1GC -XX:MaxGCPauseMillis=… |
| Лог GC в файл | -Xlog:gc*:file=… |
| OOM → дамп для MAT | -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=… |
| Профиль 60 с в проде | jcmd <pid> JFR.start … (runbook) |
| Проверить флаги процесса | jcmd <pid> VM.flags |
В Docker и Kubernetes лимит cgroup может быть меньше видимой ОЗУ хоста. С JDK 10+ учитывайте -XX:+UseContainerSupport (включён по умолчанию в современных сборках) и не ставьте -Xmx выше лимита контейнера — иначе OOMKill со стороны оркестратора раньше, чем Java heap.
25. Профилирование и мониторинг
25.1. Встроенные инструменты JDK
jps— список Java-процессовjstat— статистика GC и heapjstack— дамп стеков потоковjmap— информация о памяти, heap dumpjconsole,jvisualvm— графические инструменты мониторингаjcmd— универсальная команда для отправки команд процессу
25.2. Внешние инструменты
- VisualVM — расширенный мониторинг
- YourKit, JProfiler — коммерческие профайлеры
- Prometheus + Micrometer — метрики в production
25.3. JFR быстрые команды
jcmd <pid> JFR.start name=debug settings=profile duration=60s filename=recording.jfr
jcmd <pid> JFR.dump name=debug filename=recording.jfr
jcmd <pid> JFR.stop name=debug
При чтении JFR сначала смотрят:
- горячие методы по CPU;
- аллокации по типам/методам;
- паузы GC и частоту stop-the-world событий.
26. Отладка
26.1. Логирование
Используйте фреймворки вместо System.out.println:
- SLF4J — фасад
- Logback или Log4j2 — реализации
Пример:
private static final Logger log = LoggerFactory.getLogger(MyClass.class);
log.info("Processing user: {}", userId);
26.2. IDE-отладка
- Точки останова (breakpoints)
- Пошаговое выполнение (step into / over / out)
- Инспекция переменных
- Вычисление выражений во время отладки
27. Лучшие практики разработки на Java
27.1. Именование
- Классы —
UpperCamelCase - Методы и переменные —
lowerCamelCase - Константы —
UPPER_SNAKE_CASE - Пакеты — строчные, без подчёркиваний (
com.example.project)
27.2. Читаемость кода
- Методы короткие (до 20–30 строк)
- Одна ответственность на метод
- Избегать глубокой вложенности условий
- Использовать выразительные имена
27.3. Безопасность
- Не логировать чувствительные данные (пароли, токены)
- Валидировать входные данные
- Использовать
PreparedStatementвместо конкатенации SQL - Обновлять зависимости (CVE-уязвимости)
27.4. Производительность
- Избегать создания лишних объектов в циклах
- Использовать
StringBuilderдля конкатенации строк в цикле - Предпочитать примитивы обёрткам, где возможно
- Использовать пул соединений и потоков
27.5. Обработка ошибок
- Не игнорировать исключения
- Логировать причину ошибки (
e.getMessage(),e.getCause()) - Не выбрасывать исключения из блоков
finally - Использовать конкретные типы исключений
27.6. Неизменяемость
- Делать классы неизменяемыми, когда это возможно (
finalполя, отсутствие сеттеров) - Использовать
Collections.unmodifiableList()для защиты коллекций
27.7. Совместимость
- Указывать версию языка в
pom.xmlилиbuild.gradle - Избегать использования preview-функций в production
- Тестировать на целевой версии JVM
28. Language Basics — API-дополнение
Сводка ключевых API-акцентов для базового языка (синхронизировано с dev.java language basics):
| Тема | Что важно в production |
|---|---|
| Примитивы и обёртки | Избегать лишнего boxing в горячих участках |
equals / hashCode | Корректные контракты для коллекций и доменных типов |
switch-выражения | Явное ветвление без fall-through |
record / sealed | Меньше шаблонного кода и более строгие модели |
| Исключения | Checked/unchecked разделять по смыслу контракта |
Быстрые API-правила:
Stringсравнивать черезequals, не==.- Для денег использовать
BigDecimal, неdouble. - Для DTO в новом коде часто лучше
record. - В публичных контрактах лучше явная семантика
Optional, чем "иногда null".
record UserDto(long id, String email) {}
String level = switch (score) {
case 0, 1 -> "low";
case 2 -> "medium";
default -> "high";
};
29. Collections Framework — API-дополнение
Расширение к разделу коллекций: фокус на правильный выбор структуры и контракты.
| Структура | Брать, когда | Риск при неверном выборе |
|---|---|---|
ArrayList | дефолтный список | ожидать дешёвые вставки в середину |
LinkedList | частые вставки в начало/середину | вызывать get(index) в цикле |
HashSet | уникальные элементы | ждать стабильный порядок обхода |
HashMap | быстрый key-value | зависеть от порядка итерации |
LinkedHashMap | нужен порядок вставки | считать его автоматически sorted |
TreeMap / TreeSet | нужен сортированный обход | переплатить O(log n), когда порядок не нужен |
EnumSet | множество констант enum | использовать HashSet без причины |
ArrayDeque | очередь/стек в коде | брать Stack или Vector |
PriorityQueue | приоритет на извлечении | путать с FIFO |
ConcurrentHashMap | конкурентный доступ | заменять им всё без причины |
BlockingQueue | producer–consumer | блокировки без ограничения ёмкости |
Ключевые API-методы Map, которые реально экономят код:
Map<String, Integer> counts = new HashMap<>();
counts.merge("java", 1, Integer::sum);
counts.computeIfAbsent("streams", k -> 0);
counts.putIfAbsent("virtual-threads", 1);
Практика:
- Для неизменяемых наборов —
List.of,Set.of,Map.of. - Для очереди/стека в алгоритмах —
ArrayDeque, а неStack. - Для удаления по условию —
removeIf, а не мутация вfor-each.
30. Streams и Gatherers — API-дополнение
Дополнение к Stream API: как проектировать pipeline без потери читаемости и скорости.
| Категория | Примеры |
|---|---|
| Intermediate | filter, map, flatMap, distinct, sorted, limit |
| Terminal | toList, collect, reduce, count, findFirst, anyMatch |
| Primitive streams | IntStream, LongStream, DoubleStream |
Типовой pipeline:
Map<String, Long> byRole = users.stream()
.filter(User::isActive)
.collect(Collectors.groupingBy(User::getRole, Collectors.counting()));
Критичные правила:
- Для
toMapвсегда думайте о коллизиях ключей. parallelStream()подходит для CPU-bound, не для блокирующего I/O.peek— для отладки, не для бизнес-логики.
Про Gatherers (Java 24+) — используйте, когда нужен stateful intermediate-шаг (например, оконная обработка), а обычный pipeline получается нечитабельным или слишком аллоцирует промежуточные структуры.
31. Virtual Threads — API-дополнение
Дополнение к асинхронности и устройству virtual threads: практическая карта применения (Java 21+).
| Сценарий | Рекомендуемая модель |
|---|---|
| Массовый блокирующий I/O | virtual threads |
| CPU-bound расчёты | фиксированный пул platform threads |
| Смешанный сервис | разделение пулов CPU/I-O + таймауты |
Базовый шаблон:
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
Future<String> profile = executor.submit(() -> loadProfile(userId));
Future<List<String>> orders = executor.submit(() -> loadOrders(userId));
// ...
}
На что смотреть в эксплуатации:
- таймауты на все внешние вызовы;
- отсутствие долгого блокирующего I/O внутри
synchronized; - метрики p95/p99 и thread dump под нагрузкой.
32. Executor sizing heuristics
Практические эвристики, с которых обычно начинают:
| Тип нагрузки | Стартовая настройка |
|---|---|
| CPU-bound | размер пула около числа ядер |
| I/O-bound (platform threads) | ограниченный пул + очередь + таймауты |
| I/O-bound (virtual threads) | task-per-request + контроль таймаутов и cancellation |
Всегда проверяйте настройки под нагрузочным тестом.
- Эвристика дает старт.
- Окончательные значения подбирают по метрикам и профилю нагрузки.
Базовый разбор HTTP и HTTPS находится в отдельной статье — HTTP как основа веб-интеграций.
В подборках
Статья входит в тематические подборки и блок "С чего начать?" на главной. Соседние шаги того же маршрута:
Справочники — Справочник по конфигурациям в Java, Документация и инструменты Java (Microsoft), Справочник по Python, Справочник по F#, Справочник по Flask, Справочник по конфигурациям в C#.