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


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

РКН clck.ru/3KoGeP
Download Telegram
🧑‍💻Пишете на Vue и давно работаете с Vue Router по привычке? Сейчас в экосистеме появляется новая опция — Kitbag Router. Лёгкий повод пересобрать подход к роутингу и обновить стек.

На открытом уроке разберём, как подключить его к проекту, настроить под свой стек и чем он принципиально отличается от Vue Router. Пошагово пройдём путь от установки до рабочих маршрутов в SPA.

Вы познакомитесь с новой библиотекой роутинга для VueJS, научитесь создавать приложения с клиентским роутингом на Kitbag Router, сравнивать его с Vue Router и осознанно выбирать инструмент под задачу.

📆Встречаемся 21 января в 20:00 МСК в преддверие старта курса «Vue.js разработчик». Регистрация открыта: https://vk.cc/cTo0LX

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
🔮 Pattern Matching в Switch: Типизируй это!

Помните этот бесконечный кошмар, когда вам приходит Object, и нужно понять, что внутри?
Раньше мы писали "лестницу" из if-else и instanceof с кучей ручного кастинга (приведения типов).

Было (Боль и слезы):


Object obj = getUnknownObject();

if (obj instanceof String) {
String s = (String) obj; // Ручной каст
System.out.println("Строка: " + s.length());
} else if (obj instanceof Integer) {
Integer i = (Integer) obj; // Опять каст
System.out.println("Число: " + i);
} else if (obj instanceof Long) {
// ... и так до бесконечности
}



Стало (Java 21 LTS):
Теперь switch умеет проверять типы! Больше никаких instanceof и ручных приведений. Переменная создается прямо в кейсе.


switch (obj) {
case String s -> System.out.println("Строка: " + s.length());
case Integer i -> System.out.println("Число: " + i);
case Long l -> System.out.println("Длинное число: " + l);
default -> System.out.println("Непонятно что");
}



🛡 Guarded Patterns (Охрана в кейсах)

Но это еще не всё. Часто бывает, что тип нам подходит, но нужно проверить еще и значение.
Раньше пришлось бы ставить if внутри case. Теперь у нас есть ключевое слово when.


switch (obj) {
// Попадет сюда, ТОЛЬКО если это строка И она длиннее 10 символов
case String s when s.length() > 10 ->
System.out.println("Длинная строка: " + s);

// Любая другая строка
case String s ->
System.out.println("Короткая строка: " + s);

case Integer i ->
System.out.println("Число: " + i);

default -> {}
}



👻 А как же Null?

В старом switch, если передать null, мы мгновенно получали NullPointerException.
В новом switch можно (и нужно!) обрабатывать null легально:


switch (obj) {
case String s -> System.out.println("Это строка");
case null -> System.out.println("Пришел null!"); // Никакого NPE
default -> System.out.println("Что-то другое");
}




Это не просто "сахар". Это изменение подхода к полиморфизму.
Если раньше логика часто размазывалась по методам классов (animal.makeSound()), то теперь можно собирать логику обработки разных типов в одном месте, что часто бывает удобнее при написании бизнес-логики (например, обработка разных типов ивентов или DTO).

🔥 Итог

🔴Switch теперь принимает любые объекты.
🔴Кастинг происходит автоматически (case String s).
🔴Можно уточнять условия через when.
🔴Можно безопасно ловить null.

#PatternMatching #NewJava #CleanCode

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
👍6
🎯 Открытый урок «Сетевой чат на C#».

🗓 22 января в 20:00 МСК
🆓 Бесплатно. Урок в рамках старта курса «C# Developer».

На вебинаре:
✔️ Рассмотрим написание сетевого приложения на C#.
✔️ Мы реализуем простые клиент и сервер с помощью одного из сетевых протоколов.
✔️Также затронем темы многопточности и асинхронности

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

Что вы получите:
- По итогам вебинара смогут проектировать сетевые приложения.
- Получат представление о работе сетевых протоколов, и многопоточности\асинхронности в приложениях.
- На практике попробуют разработать такое приложение.

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

Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576
Please open Telegram to view this post
VIEW IN TELEGRAM
🔒 Sealed Classes: Архитектурный фейсконтроль

В ООП всегда была проблема с наследованием. Либо ваш класс открыт для всех («Наследуйся кто хочет!»), либо он закрыт наглухо (final).
Но что, если я хочу, чтобы мой класс Shape (Фигура) могли наследовать только Circle и Square, и больше никто?

Раньше это решалось костылями (пакетная видимость, скрытые конструкторы). В Java 17 появился официальный механизм: Sealed Classes.

🚧 Как это работает?

Вы помечаете класс (или интерфейс) ключевым словом sealed и после слова permits перечисляете тех, кому "можно".


// Родитель: Разрешает наследование ТОЛЬКО этим двум классам
public sealed interface Payment
permits CreditCard, Cash {
}



Теперь, если Вася из соседнего отдела попытается написать class Crypto extends Payment, компилятор ударит его по рукам. 🚫

🚦 Правило трех дорог

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

1. final - Цепочка наследования обрывается. Дальше наследовать нельзя.

public final class Cash implements Payment { ... }




2. sealed - Иерархия продолжается, но снова под контролем.

public sealed class CreditCard implements Payment permits Visa, MasterCard { ... }




3. non-sealed - "Открываем шлюзы". Дальше от этого класса может наследоваться кто угодно (возврат к старому поведению Java).

public non-sealed class DebitCard implements Payment { ... }





🧩 Главная фишка: Комбо со Switch

Зачем это нужно, кроме запретов? Ради безопасности.
Когда вы используете sealed иерархию в новом switch, компилятор знает все возможные варианты.

Вам больше не нужно писать ветку default!


// Метод обработки платежа
String process(Payment p) {
return switch (p) {
case CreditCard c -> "Processing card: " + c.getNumber();
case Cash c -> "Processing cash amount: " + c.getAmount();
// default НЕ НУЖЕН! Компилятор знает, что третьго не дано.
};
}



Если завтра вы добавите в permits новый класс Crypto, код перестанет компилироваться, пока вы не обработаете этот новый кейс в свитче.
Это спасает от багов, когда в бизнес-логику добавили новый тип, а обработчики обновить забыли.

🔥 Итог

Sealed Classes + Records + Switch Pattern Matching = 💎
Это "Святая Троица" современной Java. Используйте запечатанные классы для моделирования доменной области, где количество вариантов конечно и известно заранее (статусы заказа, типы платежей, виды пользователей).

#Java17 #SealedClasses #Architecture #CleanCode

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥8
🧵 Виртуальные потоки: Революция производительности

Представьте, что вы строите высоконагруженный сервер. Раньше у вас было два пути:

1. Классика (Thread): Простой код, но один поток весит ~2 Мб памяти. Создадите 5,000 потоков - сервер упадет с OutOfMemoryError.
2. Асинхронность (WebFlux/Netty): Сервер держит 100k соединений, но код превращается в лапшу из callbacks и CompletableFuture, которую невозможно отлаживать.

В Java 21 появились Виртуальные потоки. Они объединяют простоту первого подхода и производительность второго.

🪶 В чем магия?

Классический поток Java (Platform Thread) привязан 1-к-1 к потоку операционной системы (OS Thread). Это дорогой ресурс.

Виртуальный поток, это просто объект в куче (heap) JVM. Он не привязан к ОС намертво.

🔴Вес: Несколько килобайт (вместо мегабайт).
🔴Количество: Можно создать миллион виртуальных потоков на обычном ноутбуке.

⚙️ Как это работает (Carrier Threads)

Под капотом работает схема Mount/Unmount:

1. JVM запускает небольшой пул обычных потоков ОС (называются Carrier Threads, обычно их число = числу ядер CPU).
2. Ваш виртуальный поток "садится верхом" на Carrier-поток и выполняет код.
3. ⚠️ Самое важное: Как только ваш код блокируется (ждет ответа от БД, читает файл, делает Thread.sleep), JVM снимает виртуальный поток с ядра.
4. Поток ОС освобождается и тут же берет в работу другой виртуальный поток.

Итог: Ядра процессора молотят на 100%, никогда не простаивая в ожидании ввода-вывода.

💻 Код: Найди 1 отличие

API практически не изменился. Вам не нужно учить новые фреймворки.


// Старый способ (Тяжелый поток ОС)
Thread.ofPlatform().start(() -> {
System.out.println("Я ем много памяти!");
});

// Новый способ (Легкий виртуальный поток)
Thread.ofVirtual().start(() -> {
System.out.println("Я ничего не вешу!");
});

// Использование с ExecutorService (для старого кода)
try (var executor = Executors.newVirtualThreadPerTaskExecutor()) {
IntStream.range(0, 1_000_000).forEach(i -> {
executor.submit(() -> {
Thread.sleep(1000); // Блокировка теперь БЕСПЛАТНАЯ
return i;
});
});
}
// Этот код запустит миллион задач за секунду, не положив сервер.



⚰️ Конец Reactive Programming?

Многие эксперты говорят: Да.
Смысл использования сложных реактивных библиотек (RxJava, Reactor) был в том, чтобы не блокировать потоки. Виртуальные потоки делают блокировку дешевой.
Теперь вы можете писать простой, последовательный код:
var user = db.findUser();
var data = http.sendRequest(user);
...и он будет работать так же эффективно, как сложный асинхронный код.

⚠️ Когда НЕ использовать?

Виртуальные потоки идеальны для I/O задач (ждать сеть, ждать диск).
Они бесполезны для CPU-Intensive задач (майнинг, шифрование, обработка видео). Если поток не ждет, а считает, он занимает поток ОС, и виртуалка тут не поможет.

🔥 Итог
Project Loom вернул нам девиз: "Один запрос - Один поток".
Больше никаких пулов потоков с ограниченным размером. Просто создавайте новый виртуальный поток для каждой задачи.

#Java #Loom #VirtualThreads #Concurrency #HighLoad

📲 Мы в MAX

👉@BookJava
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥91