TGViewer
Channel Public Channel
Библиотека Java разработчика

Библиотека Java разработчика

@bookjava

📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


По всем вопросам @evgenycarter

РКН clck.ru/3KoGeP
Subscribers
10.1K
Photos
1.1K
Videos
603
Links
1.5K

Showing posts older than #3954 · Back to latest

Older Posts 20 shown
Post #3953 1.35K
Парсинг на Java. От основ до парсинга Яндекс Карт

Сегодня я рассмотрю основы парсинга на Java, используя как пример Яндекс Карты.

В этой статье мы рассмотрим, что такое HTTP и какие бывают методы запроса, как работать с HttpClient в Java 11+, как отправлять GET и POST-запросы, как обрабатывать HTTP-ответы и извлекать данные, и как всё это можно использовать для парсинга данных с внешнего сервера на примере Яндекс Карт.

https://habr.com/ru/companies/amvera/articles/937894/

👉 @BookJava
Post #3952 1.21K
Sealed Classes.

Sealed Classes — контроль наследования в Java 🔒

Одна из самых недооценённых фич Java 17 — sealed классы.
Если коротко: теперь ты можешь жёстко контролировать, кто именно может наследоваться от твоего класса.

До Java 17 🤯

Представь, у тебя есть базовый класс:


abstract class Shape {}


И куча наследников кто во что горазд:
Circle, Rectangle, Triangle, StarShape, ShapeFromLegacyLib...
А потом в коде появляются неожиданные "левые" реализации, и поддержка превращается в ад.


В Java 17 пришло спасение 🦸


public sealed abstract class Shape
permits Circle, Rectangle, Triangle {}


Теперь только указанные классы могут наследовать Shape.
Больше никаких сюрпризов из сторонних либ или неосторожных рук джуна.


Варианты модификаторов 🛠️

У наследников есть три опции:

1. final — дальше наследовать нельзя.


public final class Circle extends Shape {}


2. sealed — продолжаем ограничивать список наследников.


public sealed class Rectangle extends Shape
permits Square {}


3. non-sealed — снимаем ограничения, и от этого класса можно наследоваться свободно.


public non-sealed class Triangle extends Shape {}



Зачем это вообще? 🤔

✅ Чёткий контроль иерархии (никакой анархии).
✅ Более безопасный switch с pattern matching: компилятор проверяет, что ты обработал все варианты.
✅ Понятный контракт: сразу видно, какие подтипы есть.


Пример использования с switch 💡


static String print(Shape shape) {
return switch (shape) {
case Circle c -> "Круг";
case Rectangle r -> "Прямоугольник";
case Triangle t -> "Треугольник";
};
}


И всё!
Если ты забыл какой-то подтип, компилятор не даст собрать проект 🚨.


Итог ⚡️

- Sealed Classes = контроль + безопасность + читаемость.
- В паре с Pattern Matching в switch это превращается в почти алгебраические типы данных (как в Kotlin или Scala).
- Если у тебя чётко ограниченный набор сущностей — sealed классы must-have.

👉 @BookJava
  • 👍 8
  • ❤ 1
Post #3950 1.24K
Pattern Matching в switch.

Pattern Matching в switch — убийца if-else цепочек ⚔️

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


if (obj instanceof String) {
System.out.println("Строка длиной " + ((String) obj).length());
} else if (obj instanceof Integer) {
System.out.println("Целое число " + obj);
} else if (obj instanceof List) {
System.out.println("Список размером " + ((List<?>) obj).size());
} else {
System.out.println("Неизвестный тип");
}


Знакомо? 😅
Тут и дублирование, и касты, и вечная путаница.


Что пришло с Java 17+ 🌟

Теперь можно использовать Pattern Matching прямо в switch:


switch (obj) {
case String s -> System.out.println("Строка длиной " + s.length());
case Integer i -> System.out.println("Целое число " + i);
case List<?> l -> System.out.println("Список размером " + l.size());
default -> System.out.println("Неизвестный тип");
}


Красота:

✅ Нет ручных кастов
✅ Нет else if простыней
✅ Всё читается как декларативное описание

А если хочется добавить условия? 🤔

Можно так:


switch (obj) {
case String s when s.length() > 5 ->
System.out.println("Длинная строка");
case String s ->
System.out.println("Короткая строка");
default ->
System.out.println("Что-то другое");
}


Тут when — это guard condition.
Оно проверяется после совпадения типа, и только тогда срабатывает ветка.


Сравним 🥊

До Java 17: каша из if-else, ручные касты.
После Java 17: один чистый switch, никакой боли.

Итог 💡

- Используй switch с pattern matching, когда у тебя много разных подтипов или вход может быть разным типом.
- Код становится декларативным и компактным.
- А главное — исчезают дубли и лишние касты.

👉 @BookJava
  • 👍 7
Post #3949 1.41K
Когда лучше использовать record, а когда class в Java.

Record vs Class в Java ☕️📦

С 2021-го в Java появилась новая зверушка - record.
Сначала все радовались: "О, меньше кода, equals/hashCode/constructor сами пишутся!" 🎉
А потом пошли странные вопросы в код-ревью:

"А почему у тебя тут record, а не class?"
"record же immutable, а ты тут мутируешь поле через рефлексию, ты что…"


Разберёмся, когда record - подарок, а когда - мина замедленного действия.


Немного теории 📚

record в Java — это особый вид final-класса с:

- Автоматическим конструктором по всем полям.
- equals, hashCode и toString из коробки.
- Неизменяемыми (final) полями.
- Неявным private final для каждого компонента.

Это всё звучит прекрасно, но у этого есть архитектурные последствия.


Когда record - лучший выбор ✅

1. DTO / данные без логики
Когда объект нужен просто как "контейнер" для данных, особенно при обмене между сервисами.


public record UserDto(String name, int age) {}


2. Иммутабельные объекты
Нет сеттеров, нет сюрпризов. Многопоточка будет тебе благодарна ❤️.

3. Модели конфигураций
Конфиг парсится один раз — и потом спокойно читается везде.

4. Key-объекты для Map/Set
Так как equals и hashCode генерятся честно и по всем полям - отличная стабильная ключевая структура.


Когда class лучше 🚫

1. Сложная логика внутри
Если объект должен уметь менять своё состояние, record тебе мешает: поля final, сеттеров нет.

2. Наследование
Record - всегда final. Забудь про расширение.

3. ORM (например, Hibernate)
Многие ORM любят пустые конструкторы и сеттеры. С record они просто не подружатся (даже если будут пытаться через магию).

4. Сериализация с изменениями
Если JSON-модель в будущем изменится, record будет ломаться при парсинге, потому что конструктор фиксирован.


Хитрости и подводные камни ⚠️

- Можно добавлять методы в record.


public record Point(int x, int y) {
public double length() {
return Math.sqrt(x*x + y*y);
}
}

- Поля можно менять через рефлексию (но не надо — это ломает смысл record).
- Не стоит превращать record в «богатый объект» с кучей логики — это будет запутывать.


Итог 💡

- Берём record, когда нужна простая, иммутабельная структура данных без лишней логики.
- Берём class, когда есть сложное поведение, наследование, интеграция с фреймворками вроде Hibernate.

record - это не замена class, а инструмент для конкретных задач.
А вот если ты пишешь DTO и у тебя до сих пор class с геттерами/сеттерами, то, возможно, ты застрял в 2010-м 😏.

👉 @BookJava
  • ❤ 4
  • 👍 3
  • 🤡 2
Post #3947 1.5K
В чем разница между перегрузкой метода и переопределением метода в Java?

🧠 Перегрузка метода (Method Overloading)
Это когда в одном классе есть методы с одинаковым именем, но разными сигнатурами (количеством или типами параметров).

* Компилятор выбирает метод на этапе compile-time.
* Можно менять:

* количество параметров
* тип параметров
* порядок параметров
* Нельзя перегружать метод, меняя только возвращаемый тип.

💡 Пример:


public class MathUtil {
public int sum(int a, int b) { return a + b; }
public double sum(double a, double b) { return a + b; }
public int sum(int a, int b, int c) { return a + b + c; }
}



🧠 Переопределение метода (Method Overriding)
Это когда в классе-наследнике мы заново реализуем метод, который уже определён в родительском классе или интерфейсе.

* Определяется на этапе runtime (динамический полиморфизм).
* Сигнатура метода должна быть та же (имя, параметры, порядок, типы).
* Возвращаемый тип может быть ковариантным (подтипом оригинального).
* Доступ не может быть строже, чем у родительского метода.
* Метод родителя должен быть public / protected (не private).
* Для обязательности переопределения используют @Override.

💡 Пример:


class Animal {
public void makeSound() {
System.out.println("Some sound");
}
}

class Dog extends Animal {
@Override
public void makeSound() {
System.out.println("Woof!");
}
}


👉 @BookJava
  • 👍 3
Post #3946 1.33K
☕ Совет дня по Java: JDK vs JRE vs JVM

🔹 JVM (Java Virtual Machine)
Машина, которая выполняет Java-байткод, обеспечивая кроссплатформенность.

🔹 JRE (Java Runtime Environment)
Содержит JVM + необходимые библиотеки для запуска Java-приложений.

🔹 JDK (Java Development Kit)
Всё, что нужно разработчику — JRE + компилятор + инструменты для написания, компиляции и отладки Java-кода.

👉 Если запускаешь Java-приложения → тебе нужен JRE
👉 Если разрабатываешь Java-приложения → тебе нужен JDK
👉 А выполняет всю тяжёлую работу всегда JVM.

👉 @BookJava
  • 👍 2
  • ❤ 1
Post #3944 1.32K
Конструкторы в Java: виды, инициализация и примеры

В Java конструктор — это специальный метод, который автоматически вызывается при создании нового объекта. Он заботится о том, чтобы сразу «обеспечить» объект всеми необходимыми начальным значениями - как Lego‑инструкция, превращающая вас в сразу работающего робота.


Что важно знать о конструкторах:

- Конструктор по умолчанию
Создаётся автоматически, если вы не объявили ни одного конструктора. Не имеет параметров и не задаёт пользовательские значения - поля получают только значения по умолчанию.

- Конструктор с параметрами
Позволяет инициализировать объект сразу нужными данными:


House myHouse = new House(2, "Синий", true);


В этом примере мы сразу получаем дом с двумя этажами, синим цветом и гаражом - благодаря конструктору House(...).

- Конструктор копирования
Создает новую копию существующего объекта со всеми его полями - полезно, если нужно сохранить исходное состояние или избежать его изменения.


Перегрузка конструкторов - гибкость и удобство

Можно объявить несколько конструкторов в классе с разными параметрами:


class Book {
String title;
String author;
int year;

// По умолчанию
Book() {
this.title = "Неизвестно";
this.author = "Неизвестно";
this.year = 0;
}

// Только с названием
Book(String title) { /*...*/ }

// Полная инициализация
Book(String title, String author, int year) { /*...*/ }
}


Такой подход позволяет создавать объекты Book с разными уровнями наполненности в зависимости от ситуации.


Ещё один пример - класс Person


class Person {
String name;
int age;

Person(String name, int age) {
this.name = name;
this.age = age;
}
}

Person person = new Person("Алексей", 30);


Получили объект person сразу с заданными именем и возрастом - без лишнего кода.



- Конструктор = автоматическая инициализация объекта.
- Виды: по умолчанию, с параметрами, копирующий.
- Перегрузка - возможность гибко задавать разные способы создания объектов.
- Это делает код чище, логичнее и безопаснее.

👉 @BookJava
  • ❤ 2
  • 👍 2
  • 🤓 2
Post #3943 1.65K
Spring Debugger: Working With Dynamic Database Connections Just Got Simpler

Туториал демонстрирует очень крутую фичу плагина Spring Debugger. При запуске Spring-приложения или тестов в режиме отладки этот плагин автоматически находит и регистрирует в секции DataSource подключения к БД, которые были подняты в Testcontainers. Далее с этим можно работать как со стандартными дата-сорсами: смотреть схему, данные, делать запросы и так далее. Это сильно упрощает жизнь при отладке подобных тестов.

https://blog.jetbrains.com/idea/2025/07/spring-debugger-working-with-dynamic-database-connections-just-got-simpler/

👉 @BookJava
  • ❤ 3
  • 👍 1
Post #3942 1.77K
🧠 Можно ли переопределить getClass() в Java?

Нет, нельзя.
Метод getClass() в java.lang.Object объявлен так:


public final native Class<?> getClass();


📌 Почему:

- final — запрещает переопределение в наследниках.
- native — реализован в JVM, а не на Java.
- Гарантирует, что при вызове obj.getClass() всегда вернётся реальный класс объекта, без подмен и сюрпризов.

💡 Если хотите вернуть “свой” тип, делайте отдельный метод:


class MyClass {
public String getTypeName() {
return "CustomType";
}
}


⚠️ Переопределяемый getClass() сломал бы рефлексию, сериализацию и кучу системных механизмов. Именно поэтому Java защищает его.

👉 @BookJava
  • 👍 5
  • ❤ 2
Post #3941 1.92K
Распространённые заблуждения

❌ «var делает Java динамически типизированным»
Неверно: Java остаётся статически типизированным языком. Компилятор по‑прежнему проверяет типы на этапе компиляции.

❌ «var ухудшает производительность»
Неверно: Никакого влияния на выполнение. Это всего лишь синтаксический сахар.

❌ «var снижает читаемость кода»
Зависит: При правильном использовании — улучшает читаемость, убирая лишний шум. При чрезмерном — может сделать код менее понятным.

Чек‑лист быстрой миграции

[ ] Найдите многословные объявления переменных в кодовой базе
[ ] Замените очевидные случаи на var (сложные дженерики, builders)
[ ] Установите командные правила использования var
[ ] Обновите процессы код‑ревью с учётом лучших практик применения var
[ ] Используйте возможности IDE для проверки выведенных типов

Итог
Локальная типовая инференция с var — небольшое изменение, которое значительно улучшает читаемость кода и опыт разработчика. Речь не о том, чтобы писать меньше кода, а о том, чтобы писать более понятный и поддерживаемый код, избавляясь от избыточных объявлений типов.

Начните использовать var уже сегодня — и сразу заметите, насколько чище станет ваш Java‑код!

👉@BookJava
  • 👎 5
  • 👍 4
  • ❤ 1
Post #3940 1.44K
💡Совет по Java №1: Прощай, многословные объявления переменных — здравствуй, var !

Java 8 vs Java 21 — Часть 1

Одно из самых заметных улучшений при переходе с Java 8 на современные версии — это введение локальной типовой инференции, более известной как ключевое слово var. Появившееся в Java 10, это нововведение устраняет избыточные объявления типов и делает код чище и читаемее.

Проблема Java 8
В Java 8 приходилось явно указывать тип каждой локальной переменной, даже когда он был очевиден из контекста:


// Java 8 - Verbose and redundant
Map<String, List<Customer>> customersByCity = new HashMap<String, List<Customer>>();
List<String> names = Arrays.asList("Alice", "Bob", "Charlie");
Optional<Customer> customer = customerService.findById(123L);



Эта многословность становилась особенно болезненной при работе с:

- сложными обобщёнными типами,
- шаблонами Builder,
- потоковыми операциями со сложными промежуточными типами.

Решение в Java 21
С var компилятор автоматически выводит тип:


// Java 21 - Clean and concise
var customersByCity = new HashMap<String, List<Customer>>();
var names = Arrays.asList("Alice", "Bob", "Charlie");
var customer = customerService.findById(123L);


Примеры из реальной практики

1. Работа с коллекциями


// Before (Java 8)
List<Map<String, Object>> configurations = new ArrayList<Map<String, Object>>();
Map<String, List<ValidationResult>> validationResults = new ConcurrentHashMap<String, List<ValidationResult>>();

// After (Java 21)
var configurations = new ArrayList<Map<String, Object>>();
var validationResults = new ConcurrentHashMap<String, List<ValidationResult>>();

2. Шаблоны проектирования


// Before (Java 8)
HttpURLConnection connection = (HttpURLConnection) new URL("https://api.example.com")
.openConnection();

// After (Java 21)
var connection = (HttpURLConnection) new URL("https://api.example.com")
.openConnection();
```Java

3. Потоковые операции

```Java
// Before (Java 8)
Stream<String> filteredNames = customers.stream()
.map(Customer::getName)
.filter(name -> name.startsWith("A"));

// After (Java 21)
var filteredNames = customers.stream()
.map(Customer::getName)
.filter(name -> name.startsWith("A"));


Когда использовать var (лучшие практики)
✅ Хорошие случаи использования:


// Clear from initialization
var users = new ArrayList<User>();
var config = ConfigurationBuilder.create().build();
var response = httpClient.execute(request);

// With method calls that have descriptive names
var isValid = validator.validateEmail(email);
var totalAmount = calculator.computeTotal(items);


❌ Избегайте использования, когда:


// Type is not obvious
var data = processData(); // What type is this?
var result = calculate(); // Unclear return type

// Primitives where explicitness helps
int count = 0; // Better than var count = 0;
boolean isActive = true; // Better than var isActive = true;

Стратегия миграции
Постепенный подход к внедрению:

- Начните с очевидных случаев: сложные обобщённые типы, шаблоны Builder.
- Сфокусируйтесь на читаемости: используйте var там, где он улучшает восприятие кода.
- Поддерживайте единообразие: выработайте командные правила использования var.
- Проводите ревью и рефакторинг: обновляйте существующий код в процессе регулярного сопровождения.

Поддержка в IDE:
Большинство современных IDE отлично работают с var:

- IntelliJ IDEA: предлагает подсказки и отображает выведенные типы.
- Eclipse: показывает информацию о типе при наведении курсора.
- VS Code: расширения для Java поддерживают отображение выведенных типов.

Влияние на производительность
var — это исключительно функция времени компиляции, без какого‑либо накладного расхода во время выполнения. Сгенерированный байткод полностью идентичен коду с явно указанными типами.

👉@BookJava
  • 👍 4
  • 👎 3
  • ❤ 2
Post #3938 1.52K
💡10 незаменимых советов и приёмов Java, которые должен знать каждый разработчик


1. Используйте улучшенный цикл for
Улучшенный цикл for, появившийся в Java 5, позволяет лаконично и эффективно проходить по массивам и коллекциям. Вместо традиционного цикла с индексами можно итерироваться напрямую по элементам, что повышает читаемость кода и снижает вероятность ошибок выхода за пределы массива.


int[] numbers = {1, 2, 3, 4, 5};
for (int number : numbers) {
System.out.println(number);
}


2. Используйте дженерики (Generics)
Дженерики позволяют создавать переиспользуемый код, работающий с разными типами данных. Они обеспечивают безопасность типов и избавляют от необходимости явного приведения типов. Результат — более надёжный и удобный для поддержки код.


List<String> names = new ArrayList<>();
names.add("John");
names.add("Jane");
String firstName = names.get(0);


3. Применяйте StringBuilder для работы со строками
При конкатенации большого количества строк или частых изменениях строки класс StringBuilder работает эффективнее, чем оператор + или методы конкатенации. StringBuilder изменяем (mutable) и предоставляет удобные методы для работы со строками.


StringBuilder message = new StringBuilder("Hello");
message.append(" World");
message.insert(5, " Java");
String result = message.toString();


4. Понимайте управление памятью в Java
Java автоматически управляет памятью через механизм сборщика мусора, но важно понимать, как создаются, используются и уничтожаются объекты. Грамотное управление памятью помогает избежать утечек и повышает производительность приложения.

5. Используйте неизменяемые классы (Immutable)
Неизменяемые классы потокобезопасны и дают преимущества в кэшировании, работе с многопоточностью и повышении безопасности. Создавая неизменяемые классы, вы исключаете риск случайных изменений и обеспечиваете целостность данных.

6. Применяйте try-with-resources
При работе с ресурсами, которые нужно закрывать (например, файлы или подключения к базе данных), конструкция try-with-resources гарантирует автоматическое закрытие ресурсов, даже если произойдут исключения. Это упрощает управление ресурсами и снижает риск утечек.


try (FileReader fileReader = new FileReader("data.txt");
BufferedReader bufferedReader = new BufferedReader(fileReader)) {
String line = bufferedReader.readLine();
// Process the data
} catch (IOException e) {
// Handle the exception
}


7. Используйте перечисления (enum) для констант
Если у вас есть набор связанных констант, лучше использовать enum, а не простые переменные или целочисленные константы. Перечисления обеспечивают безопасность типов, улучшают читаемость кода и легко расширяются.


enum Days {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
Days today = Days.MONDAY;


8. Оптимизируйте циклы с помощью break и continue
Оператор break позволяет выйти из цикла досрочно, а continue — пропустить текущую итерацию и перейти к следующей. Грамотное использование этих операторов делает код более эффективным и читаемым.


for (int i = 1; i <= 10; i++) {
if (i == 5) {
break; // Exit the loop when i equals 5
}
if (i % 2 == 0) {
continue; // Skip even numbers
}
System.out.println(i);
}


9. Используйте библиотеки и фреймворки
В экосистеме Java есть огромное количество библиотек и фреймворков, которые упрощают разработку. Применяйте популярные решения вроде Apache Commons, Gson или Jackson для задач работы с файлами, JSON или базами данных. Это экономит время и избавляет от необходимости «изобретать велосипед».

10. Практикуйте грамотную обработку ошибок
Обработка ошибок — ключ к созданию надёжного и поддерживаемого кода. Используйте механизмы исключений для корректного перехвата и обработки ошибок. Логируйте важные сообщения и давайте пользователям понятную обратную связь при возникновении ошибок. Это облегчает отладку и улучшает пользовательский опыт.

👉@BookJava
  • 👍 5
  • ❤ 4
  • 🔥 4
Post #3937 1.78K
В чём разница между == и .equals() при сравнении строк?

== сравнивает ссылки на объекты (адреса в памяти), а .equals() сравнивает содержимое строк. Для сравнения строк всегда используйте .equals().

Вот пример, иллюстрирующий разницу:


String str1 = "Hello";
String str2 = "Hello";
String str3 = new String("Hello");
System.out.println(str1 == str2); // true (один и тот же объект)
System.out.println(str1 == str3); // false (разные объекты)
System.out.println(str1.equals(str2)); // true (одинаковое содержимое)
System.out.println(str1.equals(str3)); // true (одинаковое содержимое)


👉@BookJava
  • 👍 7
  • 💩 2
Post #3936 1.95K
Какова цель ключевого слова static в Java?

Ключевое слово static в Java используется для объявления членов (переменных, методов, вложенных классов), которые принадлежат самому классу, а не его экземплярам.

Объявление статических членов позволяет делиться данными между всеми экземплярами класса, создавать утилитарные методы, которые не требуют создания объекта, или определять ограничения.

Например, в следующем классе BankAccount переменные totalAccounts и INTEREST_RATE являются статическими, поэтому они будут доступны только внутри самого класса.


public class BankAccount {
private String accountHolder;
private double balance;
private static int totalAccounts = 0;
private static final double INTEREST_RATE = 0.05;


// The rest of the code here ...
}


👉@BookJava
  • 👍 4
  • ❤ 1
  • 🔥 1
Post #3934 1.67K
Как обрабатывать исключения в Java?

Исключения в Java можно аккуратно обрабатывать с помощью блоков try-catch. В блоке try пишется код, который может выбросить исключение, а в блоке catch — что нужно сделать, если это исключение произошло.

Блок finally можно использовать для операций очистки, если в try-catch задействованы внешние ресурсы, такие как файловые менеджеры, соединения с базой данных и т.д.

Вот пример кода, демонстрирующий обработку исключений в Java:


import java.io.FileReader;
import java.io.IOException;
public class ExceptionHandlingExample {
public static void main(String[] args) {
FileReader reader = null;
try {
reader = new FileReader("nonexistent.txt");
// Code that might throw an exception
int character = reader.read();
System.out.println((char) character);
} catch (IOException e) {
// Handling the specific exception
System.out.println("An error occurred while reading the file: " + e.getMessage());
} finally {
// Cleanup code that always executes
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
System.out.println("Error closing file: " + e.getMessage());
}
}
}
}
}


👉@BookJava
  • ❤ 2
  • 👍 2
Post #3933 1.77K
Совет 💡

Добавьте в JDBC URL свойство ApplicationName (зависит от БД, не в каждой БД оно есть!). Таким образом, в списке сессий вместо имени JDBC-драйвера будет отображаться имя набора. Это поможет при поиске неисправностей, когда несколько приложений подключаются к одной и той же БД.

👉@BookJava
  • 👍 10
  • ❤ 3
Post #3931 2.14K
🧠 Быстрый профилинг Java: -XX:+PrintCompilation

Хотите понять, что JIT-компилятор делает с вашим кодом и где реально тратится время?
Есть скрытая, но очень полезная фича JVM — флаг:


java -XX:+UnlockDiagnosticVMOptions -XX:+PrintCompilation -jar app.jar


📌 Что даёт?
JVM начнёт логировать все методы, которые JIT компилирует, и в какой момент.
Вы увидите:

- какие методы вызываются чаще всего (горячие точки);
- какие инлайнятся и оптимизируются;
- где есть неожиданные “узкие места”.

💡 Зачем это нужно?

- Быстро найти кандидатов на оптимизацию;
- Понять, почему приложение медленно стартует (компиляция тяжёлых методов);
- Увидеть, какие части кода JIT не трогает (и, возможно, почему).

⚠️ Нюанс: это диагностический инструмент. На продакшене лучше использовать аккуратно (или дублировать трафик на стенд).

👉 Хочешь глубже? Смотри ещё -XX:+PrintInlining — покажет какие методы JVM решила инлайнить (и почему отказалась).

Быстрый взгляд на JIT — и вы понимаете поведение кода куда глубже.

👉@BookJava
  • 👍 8
  • ❤ 1
  • 🔥 1
Post #3929 1.98K
Функциональное программирование в Java с использованием потоков (Streams) и лямбд (Lambdas)

Потоки обрабатывают фильтрацию, сортировку и агрегацию, а лямбды упрощают определение функций.
В Spring они лежат в основе реактивных API, а в соревновательном программировании — позволяют оптимизировать работу с данными.
Пример ниже демонстрирует REST-эндпоинт на Spring для фильтрации пользователей и алгоритм в стиле соревнований для поиска лучшего игрока.

👉@BookJava
  • 👍 3
  • 👎 2
  • ❤ 1
Post #3928 1.92K
🧠 Как ускорить Spring Boot при старте: spring-context-indexer

При старте Spring Boot-приложения много времени уходит на classpath scanning. Даже если вы используете @ComponentScan, Spring всё равно перебирает кучу классов в поиске бин-кандидатов. Это рефлексивно и медленно.

📌 Есть способ это оптимизировать — spring-context-indexer.

🔧 Что делать

1. Добавьте зависимость в pom.xml:


<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-indexer</artifactId>
<version>6.1.3</version> <!-- актуальная для Spring Boot 3 -->
<optional>true</optional>
</dependency>


2. Всё! Spring Boot на этапе компиляции сгенерирует индекс классов с аннотациями (@Component, @Service, @Repository, и т.п.) в META-INF/spring.components.

3. При старте приложения Spring сначала смотрит в индекс, а не сканирует classpath целиком.

💡 Полезно, если:

- У вас много модулей;
- Вы используете fat JAR;
- Приложение долго стартует и важна скорость.

⚠️ Важно

- Работает только с аннотациями Spring, не с кастомными;
- Не забудьте включить annotation processing в IDE (особенно в IntelliJ: Settings → Build, Execution, Deployment → Compiler → Annotation Processors).

📊 Профит: в крупных проектах — до 30–50% ускорения старта.

👉@BookJava
  • 👍 6
  • ❤ 4
Post #3926 1.41K
Определение и отличие IP адресов LAN, PPP в Java

Чтобы определить IP-адрес локальной машины с использованием Java, примените следующий код:


import java.net.*;

public class GetIP {
public static void main(String[] args) throws UnknownHostException {
System.out.println(InetAddress.getLocalHost().getHostAddress());
}
}


Работа с несколькими сетевыми интерфейсами

Если ваш компьютер оснащён несколькими сетевыми интерфейсами, иногда бывает необходимо обойти весь список интерфейсов и отфильтровать адреса, не являющиеся обратными петлями и являющиеся локальными для сайта. Это особенно актуально при работе в средах с многочисленными сетями.


import java.net.*;
import java.util.*;

public class GetMultiIPs {
public static void main(String[] args) throws SocketException {
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()) {
NetworkInterface iface = interfaces.nextElement();
if (iface.isLoopback() || !iface.isUp()) continue;

Enumeration<InetAddress> addresses = iface.getInetAddresses();
while(addresses.hasMoreElements()) {
InetAddress addr = addresses.nextElement();
if (addr instanceof Inet4Address) {
System.out.println(iface.getDisplayName() + " – " + addr.getHostAddress());
}
}
}
}
}


👉@BookJava
  • 👍 2
  • 🤓 2
Older posts →
Threads Profile ViewerView any public Threads profile without an account.Open ThreadLook →Writing with AI? Make it sound human.Metric37 rewrites AI drafts so they read naturally. Free AI detector, 1,500 words free.Try Metric37 →