Библиотека Java разработчика
10.6K subscribers
1.16K photos
594 videos
58 files
1.48K links
📚 Лайфхаки, приёмы и лучшие практики для Java-разработчиков. Всё, что ускорит код и прокачает навыки. Java, Spring, Maven, Hibernate.


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

РКН clck.ru/3KoGeP
Download Telegram
🎁 Optional: Лекарство от NullPointerException

Тони Хоар назвал изобретение null своей "ошибкой на миллиард долларов". NullPointerException (NPE) - самый частый кошмар Java-разработчика.
В Java 8 появился Optional<T> - класс-обертка, который явно говорит: "Здесь значения может и не быть".

📦 Что внутри?

Представьте Optional как коробку.

🔴В ней может лежать объект (Non-empty).
🔴Или она может быть пустой (Empty).

Главное правило: Никогда не возвращайте null из метода, если можно вернуть Optional.empty().

🚫 Как делать НЕ надо

Самая частая ошибка новичка, использовать Optional как старый добрый if (x != null):


Optional<User> userOpt = findUser("Alex");

// ПЛОХО: Это тот же null-check, только сложнее
if (userOpt.isPresent()) {
System.out.println(userOpt.get().getName());
}



Метод .get() - это зло. Если коробка пуста, он бросит NoSuchElementException, и вы просто поменяли шило (NPE) на мыло.

Как делать НАДО (Functional Style)

Вся мощь Optional раскрывается, когда вы строите цепочки вызовов, как в стримах.

1. Если значение есть, сделай что-то (ifPresent)


findUser("Alex").ifPresent(user -> System.out.println(user.getName()));



2. Если значения нет, верни дефолт (orElse)


// Вернет юзера или создаст нового "Guest", если не нашел
User user = findUser("Alex").orElse(new User("Guest"));



3. Если значения нет — брось ошибку (orElseThrow)


User user = findUser("Alex")
.orElseThrow(() -> new IllegalArgumentException("User not found"));



4. Преобразование внутри коробки (map)
Допустим, нам нужен не сам юзер, а его email. Если юзера нет, то и email нет.


String email = findUser("Alex")
.map(User::getEmail) // Достаем email (если юзер есть)
.map(String::toUpperCase) // В верхний регистр (если email был)
.orElse("UNKNOWN"); // Если хоть на одном этапе было пусто



Золотые правила использования

1. Только для возвращаемых значений! Не используйте Optional как тип поля в классе или аргумент метода. Это лишний оверхед и мусор в коде.
2. orElse() vs orElseGet():
🔴orElse(new Object()) - объект создается всегда, даже если он не нужен.
🔴orElseGet(() -> new Object()) - объект создается только если в коробке пусто (лениво). Используйте этот вариант для тяжелых объектов.


🔥 Итог

Optional спасает не тем, что убирает null, а тем, что заставляет вас явно обработать случай отсутствия значения.
Забудьте про .get(). Используйте .map(), .filter() и .orElse().

#Java #Optional #CleanCode #NoMoreNPE

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍53🔥2
⌨️ Открытый урок «Spring AI: от изображения к данным. Практика распознавания документов».

🗓 15 января в 20:00 МСК

🆓 Бесплатно. Урок в рамках старта курса «Разработчик на Spring Framework».

На вебинаре:
✔️ Введение в Spring AI для обработки документов.
✔️ Настройка проекта: зависимости и конфигурация модели.
✔️ Ключевые концепции: работа с изображениями, системные промпты, OutputParser.
✔️ Сервисный слой: оркестрация шагов AI-пайплайна.
✔️ REST API для загрузки/анализа, обработка ошибок и масштабирование.

Кому будет интересно:
Java-разработчикам на Spring, backend-инженерам, архитекторам и тимлидам, которым нужно встроить распознавание документов в сервисы.

Результаты после вебинара:
Соберете простой пайплайн: загрузка изображения → извлечение текста → JSON. Поймете, где в Spring AI применять промпты и OutputParser.

🔗 Ссылка на регистрацию: https://vk.cc/cTkeIQ

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
💿 Java Records: Убийцы бойлерплейта

Сколько раз вы создавали класс просто чтобы "перенести данные" из точки А в точку Б?
Вы пишете 3 поля, а потом IDE генерирует вам 50 строк кода: конструктор, геттеры, equals, hashCode, toString... 🤯

В Java 16+ этому положили конец. Встречайте Records.

📉 Было vs Стало

Допустим, нам нужен простой DTO для пользователя.

Классический POJO (Java 1.0 - 15):


public class User {
private final String name;
private final int age;

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

public String getName() { return name; }
public int getAge() { return age; }

// + equals()
// + hashCode()
// + toString() ... еще 30 строк кода
}



Record (Java 16+):


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



Всё. Это одна строка. 🔥

⚙️ Что происходит под капотом?

Компилятор делает всю грязную работу за вас. Создавая record, вы автоматически получаете:

1. Приватные финальные поля (private final).
2. Конструктор со всеми аргументами.
3. Геттеры (без префикса get! Просто .name(), .age()).
4. equals() и hashCode() (идеально для ключей в Map или Set).
5. toString() (красивый вывод: User[name=Alex, age=25]).

🛠 Кастомизация (Compact Constructor)

"А что, если мне нужна валидация? Нельзя же создать юзера с отрицательным возрастом!"
Для этого есть Компактный конструктор. Вам даже не нужно перечислять аргументы:


public record User(String name, int age) {
// Компактный конструктор
public User {
if (age < 0) {
throw new IllegalArgumentException("Возраст не может быть меньше 0");
}
// Присваивание this.age = age происходит автоматически!
}
}



⚠️ Ограничения (Важно знать)

Records, это не замена обычным классам во всем.

1. Они неизменяемы (Immutable). Сеттеров нет и не будет. Хотите поменять поле? Создавайте новый объект.
2. Нет наследования. Record не может наследовать (extends) другой класс (потому что он уже наследует java.lang.Record). Но имплементировать интерфейсы (implements) можно!

💡 Когда использовать?

🔴DTO (Data Transfer Objects): Ответы от API, запросы в БД.
🔴Ключи для Map: Благодаря гарантированному equals/hashCode.
🔴Внутри методов: Можно объявлять локальные рекорды прямо внутри метода, чтобы временно сгруппировать данные.

Records делают код чище и безопаснее. Они идеально сочетаются со Stream API, где данные постоянно передаются и преобразуются.
Если ваш класс это просто "мешок с данными", превращайте его в record.

#Java #Records #NewJava #CleanCode

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍41