Java | Фишки и трюки
Open in Telegram
Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg
Show more6 681
Subscribers
-524 hours
-267 days
-6830 days
Posts Archive
6 682
Как тебе живется, когда тебя прослушивают?
Или смс которую вы удаляете и думаете, что никто не видит. Например главные герои этого поста:
15 переписок знаменитостей которые мало кто видел смотреть переписки
Прослушка звонков от хакеров интернета разговор на 24 минуты
База городов которые переполнены плохой продукцией и просрочкой Новосибирск лидирует, а твой город?
Вступай, тут все о твоей защите — @Код Безопасности
6 682
🔄 Observer на чистом Java — реакция без Spring и магии
Нужно, чтобы один объект реагировал на изменения другого? Без тайных фреймворков, просто на Java?
Решение — паттерн Наблюдатель (Observer). Он позволяет подписчикам автоматически узнавать об изменениях.
📦 Минимальный пример:
// Observable (Subject)
class NewsAgency {
private List<NewsListener> listeners = new ArrayList<>();
public void addListener(NewsListener l) {
listeners.add(l);
}
public void publish(String news) {
for (NewsListener l : listeners) {
l.update(news);
}
}
}
// Observer (Listener)
interface NewsListener {
void update(String news);
}
// Конкретный подписчик
class TelegramBot implements NewsListener {
public void update(String news) {
System.out.println("🔔 Telegram получил: " + news);
}
}
▶️ Использование:
public class Main {
public static void main(String[] args) {
NewsAgency agency = new NewsAgency();
agency.addListener(new TelegramBot());
agency.publish("Java 21 уже вышел!");
agency.publish("🧵 Loom теперь в preview!");
}
}
📤 Вывод:
🔔 Telegram получил: Java 21 уже вышел! 🔔 Telegram получил: 🧵 Loom теперь в preview!🛠 Можно сделать гибче: Добавь нескольких подписчиков:
class EmailNotifier implements NewsListener {
public void update(String news) {
System.out.println("📧 Email-рассылка: " + news);
}
}
agency.addListener(new EmailNotifier());
Теперь все слушатели получают событие одновременно.
🗣️ Запомни: Паттерн Observer — отличный способ организовать реактивное поведение без зависимости от GUI, фреймворков или событийных систем. Работает в CLI, бэкенде, десктопе и даже Arduino. Просто и гибко.6 682
📈 Покрытие кода с JaCoCo — видишь всё, что тесты реально проверяют
Нужен простой способ понять, какие строки кода вообще исполняются при тестировании?
JaCoCo делает это красиво: запускаешь тесты — получаешь отчёт в HTML с краской по строкам.
🔧 Пример настройки под Maven:
В pom.xml добавляешь:
<plugin>
<groupId>org.jacoco</groupId>
<artifactId>jacoco-maven-plugin</artifactId>
<version>0.8.10</version>
<executions>
<execution>
<goals>
<goal>prepare-agent</goal>
</goals>
</execution>
<execution>
<id>report</id>
<phase>verify</phase>
<goals>
<goal>report</goal>
</goals>
</execution>
</executions>
</plugin>
Теперь просто запускаешь:
mvn clean verify
После этого открой отчёт:
open target/site/jacoco/index.html
🎨 Там ты увидишь список классов, методов, строки — зелёные (исполнялись), красные (нет).
👀 Пример из жизни:
Есть метод:
public int divide(int a, int b) {
if (b == 0) throw new IllegalArgumentException("zero");
return a / b;
}
Если тесты вызывают только divide(10, 2) — то строка с исключением будет красной (не покрыта).
Значит, ты пропустил случай деления на 0 — тест не полный.
📌 Хоть это и "плагин", на практике — очень мощный инструмент: видишь, где тесты работают, а где просто "для галочки".
Тесты без покрытия — это как замок на двери без ключа. Видимость есть, защиты нет.
🗣️ Запомни: JaCoCo не требует сложной настройки, но даёт мощную обратную связь. Смотришь отчёт — видишь, где твой код «голый». А дальше решаешь: прикрыть или оставить так.6 682
⌨️ Что такое класс Object? Какие в нем есть методы?
Object это базовый класс для всех остальных объектов в Java. Любой класс наследуется от Object и, соответственно, наследуют его методы:
public boolean equals(Object obj) – служит для сравнения объектов по значению;
int hashCode() – возвращает hash код для объекта;
String toString() – возвращает строковое представление объекта;
Class getClass() – возвращает класс объекта во время выполнения;
protected Object clone() – создает и возвращает копию объекта;
void notify() – возобновляет поток, ожидающий монитор;
void notifyAll() – возобновляет все потоки, ожидающие монитор;
void wait() – остановка вызвавшего метод потока до момента пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;
void wait(long timeout) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;
void wait(long timeout, int nanos) – остановка вызвавшего метод потока на определённое время или пока другой поток не вызовет метод notify() или notifyAll() для этого объекта;
protected void finalize() – может вызываться сборщиком мусора в момент удаления объекта при сборке мусора.
#java #Object #methods6 682
🔍Тестовое собеседование с Java-разработчиком из Т1 Иннотех уже завтра
4 июня(уже завтра!) в 19:00 по мск приходи онлайн на открытое собеседование, чтобы посмотреть на настоящее интервью на Middle Java-разработчика.
Как это будет:
📂 Илья Аров, старший разработчик в Т1, будет задавать реальные вопросы и задачи разработчику-добровольцу
📂 Илья будет комментировать каждый ответ респондента, чтобы дать понять чего от вас ожидает собеседующий на интервью
📂 В конце можно будет задать любой вопрос Илье
Это бесплатно. Эфир проходит в рамках менторской программы от ШОРТКАТ для Java-разработчиков, которые хотят повысить свой грейд, ЗП и прокачать скиллы.
Переходи в нашего бота, чтобы получить ссылку на эфир → @shortcut_sh_bot
Реклама. ООО "ШОРТКАТ", ИНН: 9731139396, erid: 2VtzqxDxkJq
6 682
☕️ Java - Полный Курс по Java
Этот курс охватывает основы Java, включая установку JDK, работу с переменными, условными операторами, циклами и объектно-ориентированным программированием. Подходит для тех, кто только начинает знакомство с языком🤩 Java Фишки и трюки || #Видео
6 682
Релиз через два дня. Код готов. Почти...
Остались тесты. Ну, точнее — покрытие. Потому что QA уже дышит в затылок, а ты сидишь и выбираешь: спать или корпеть до утра.
Explyt Test умеет создавать тесты под твой код — сам. Быстро. В IDE. Без плясок.
Хочешь, чтобы релиз прошёл, а не пролетел? Попробуй бесплатно! 👉 explyt.ai
6 682
🚀 Кеширование с
@Cacheable — быстро и просто в Spring
Когда метод тяжёлый (долго считает, лезет в БД или API) — зачем вызывать его 100 раз, если результат тот же?
Решение: кеш. В Spring это делается одной аннотацией.
✅ Что делает @Cacheable?
Она сохраняет результат метода в кеш.
При повторном вызове с теми же аргументами — возвращает значение из кеша, не запуская метод снова.
@Cacheable("users")
public User getUserById(Long id) {
System.out.println("Fetching from DB...");
return userRepository.findById(id).orElseThrow();
}
Первый вызов: метод выполнится → результат кешируется.
Следующие вызовы с тем же id: результат берётся из кеша.
⚙️ Как включить кеш?
1. Добавь зависимость (если ещё нет):
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
2. Включи кеш в @Configuration:
@EnableCaching
@SpringBootApplication
public class MyApp { }
Spring по умолчанию использует простой in-memory кеш (ConcurrentHashMap), но можно подключить Caffeine, Redis, Ehcache и т.д.
🔍 Продвинутые фишки:
🎯 Ключ кеша по полям:
@Cacheable(value = "products", key = "#category + ':' + #limit")
public List<Product> getTopProducts(String category, int limit) { ... }
⛔️ Пропуск кеша при null:
@Cacheable(value = "data", unless = "#result == null")
public Data fetchData(String key) { ... }
🔁 Обновление кеша вручную:
@CachePut("users")
public User updateUser(User user) { ... }
🧹 Очистка кеша:
@CacheEvict(value = "users", key = "#id")
public void deleteUser(Long id) { ... }
🗣 Запомни:@Cacheable — это «копим и не дёргаем зря».
С ним ты ускоряешь работу приложения без лишнего кода, особенно если есть дорогие вызовы (БД, сеть, парсинг).6 682
Устали от продакшн-огня, но не хотите уходить из IT? ❤️🔥
В автоматизации тестирования не горит и обычно не падает в пятницу вечером. Зато кодить всё ещё нужно.
Приходите на вебинар «Автотест на Java и карьера QA-автоматизатора» — в четверг, 5 июня.
▶️▶️ Занять место ▶️
Занятие проводят инженеры QA.GURU, создатели авторской программы по обучению автоматизации.
Что будет?
— узнаете, чем отличается Manual от Automation QA;
— разберетесь, куда двигается рынок, и почему автоматизаторы нужны всем.
А еще на занятии вы:
— напишете свой автотест на Java: логин, поиск в Google шаг за шагом;
— подключите Web, Mobile и API в одном проекте.
Спикер, Станислав Васенков — QA-инженер, 10+ лет в автоматизации, ex-Head of QAA pflb.ru и автор библиотеки allure-notifications, спикер QA-митапов. Победитель хакатона по автоматизации тестирования от Epam.
На нашей встрече Стас покажет, как специалисту с бэкграундом в разработке стартовать в автоматизации.
🎯 Будет интересно,если вы:
— Java-разработчик, который хочет уйти от багфиксов, но остаться в IT;
— ищете менее выгорающий трек с хорошей техбазой;
— хотите понять, как устроена современная автоматизация и где вы в ней можете быть полезны.
Участие бесплатное, но нужна регистрация.
▶️ Занять место можно до четверга.
Реклама. Рекламодатель: ИП Васенков Станислав Олегович, ИНН 774335827403, erid: 2VtzqvJaFC1
6 682
🏭 Factory в Java: просто, без бойлерплейта
Factory-паттерн — это способ создавать объекты, не раскрывая логику создания. Но в Java он часто обрастает шаблонами, абстракциями и XML'ем. Зачем? Можно проще.
Допустим, у нас есть интерфейс:
interface Notification {
void send(String message);
}
И реализации:
class EmailNotification implements Notification {
public void send(String message) {
System.out.println("Email: " + message);
}
}
class SmsNotification implements Notification {
public void send(String message) {
System.out.println("SMS: " + message);
}
}
➡️ А теперь сама Factory — без лишнего:
class NotificationFactory {
public static Notification create(String type) {
return switch (type) {
case "email" -> new EmailNotification();
case "sms" -> new SmsNotification();
default -> throw new IllegalArgumentException("Unknown type");
};
}
}
Использование:
Notification n = NotificationFactory.create("email");
n.send("Hello world!");
✔️ Что получили:
1. 👍 Централизованное создание объектов
Меняем реализацию в одном месте.
2. 👍 Гибкость без наследования
Можно возвращать любые классы — хоть анонимные, хоть лямбды.
3. 👍 Без бойлерплейта
Никаких XML, DI-фреймворков и пяти уровней абстракции.
⚠️ Но не переусердствуй:
1. 🟢 Не делай фабрику ради фабрики
Если new работает — не трогай.
2. 🟢 Не забывай про enum
Часто enum c фабрикой — читается лучше, чем строки.
🗣️ Запомни: Factory — это не про паттерны ради паттернов. Это про чистый код и простую подмену реализаций. Не усложняй — Java и так может быть элегантной.6 682
☕️Text Blocks в Java: читаемые строки без \n и слёз
До Java 13 работа с многострочными строками была болью. JSON? HTML? SQL? Только через
"\n" + и кучу экранирования.
Но с Text Blocks всё стало проще, понятнее и читаемо.
Сравни:
❌ До:
String html = "<html>\n" +
" <body>Hello</body>\n" +
"</html>";
✅ После (Text Block):
String html = """
<html>
<body>Hello</body>
</html>
""";
➡️ Стало чище, короче и как в оригинале. Это обычная String, просто оформленная красиво.
✔️ Преимущества Text Blocks:
1. 👍 Читаемость на уровне "как есть"
Код больше не превращается в кашу. Особенно полезно для:
SQL-запросов:
String query = """
SELECT id, name
FROM users
WHERE active = true
ORDER BY created_at DESC
""";
HTML/JSON шаблонов:
String json = """
{
"name": "Alice",
"role": "admin"
}
""";
2. 👍 Меньше экранирования
Забудь про \", \\n, \\t — теперь можно писать почти как в блокноте.
3. 👍 Автоматическое выравнивание
Java сама уберёт начальные отступы на основе самой "узкой" строки.
Пример:
String msg = """
Line 1
Line 2
Line 3
""";
➡️ Результат будет:
Line 1 Line 2 Line 34. 👍 Интеграция с
.formatted()
Нельзя вставить переменные прямо в Text Block?
Используем .formatted() — коротко и читабельно:
String user = "Bob";
String template = """
{
"user": "%s",
"access": "granted"
}
""".formatted(user);
````
```java
String s = """
Hello""";
System.out.println(s.length()); // 6, а не 5 (есть \n)
3. 🟢 Нет интерполяции переменных
Нельзя писать так:
String name = "Eve";
String wrong = """
Hello, $name!
"""; // ❌ не сработает
Вместо этого:
String right = """
Hello, %s!
""".formatted(name);
🗣️ Запомни: Text Blocks делают строки в Java человечными. Это не просто сахар — это инструмент, чтобы твой код говорил с тобой на одном языке. Используй их для всего, что требует форматирования — и забудь про + "\n".6 682
☕️
final в Java — стоп-сигнал для изменений
В Java final — это как «не трогай»: запрет на изменение.
Но что именно он запрещает? Всё зависит от того, где его поставить: переменная, метод, класс.
Разберёмся 👇
1. 📦 final переменные — нельзя переназначить
final int port = 8080;
port = 9090; // ❌ ошибка компиляции
➡️ Значение фиксируется один раз. Для примитивов — это само значение, для объектов — это ссылка.
final List<String> list = new ArrayList<>();
list.add("Hello"); // ✅ можно
list = new ArrayList<>(); // ❌ нельзя
🧠 Важно: final не делает объект неизменяемым. Только ссылку.
2. 🔒 final методы — нельзя переопределить в наследниках
class Animal {
final void sleep() {
System.out.println("Zzz...");
}
}
class Dog extends Animal {
// ❌ Нельзя переопределить sleep()
}
➡️ Полезно, если хочешь защитить логику метода от изменений в подклассах.
3. 🧱 final классы — нельзя наследовать вообще
final class Utility {
static void log(String msg) { ... }
}
class MyUtil extends Utility {} // ❌ ошибка
➡️ Применяют для:
🟢 утилитарных классов (Math, String)
🟢 защиты от подмены логики (SecurityManager, System)
🎯 Частые применения в дикой природе:
🟢 final аргументы в методах → защищает от случайного переназначения
🟢 final поля + @Immutable → хорошая практика для DTO
🟢final классы → в record, enum, String, LocalDate и т.д.
🗣 Запомни:final = контроль. Это способ сказать «вот это трогать нельзя». Используй его осознанно — чтобы сделать поведение предсказуемым и безопасным.6 682
🔄
stream().map().filter().collect() — читаемо и мощно
Java Stream API — это как grep | awk | sort в Linux, только в Java-стиле.
Самая частая связка: map → filter → collect. И она может заменить кучу шаблонного кода.
Допустим, у нас есть список:
List<String> names = List.of("Alice", "bob", "CHARLIE", "dave");
👉 Хочешь получить отфильтрованные, приведённые к верхнему регистру имена, которые длиннее 3 символов?
До Stream API:
List<String> result = new ArrayList<>();
for (String name : names) {
String upper = name.toUpperCase();
if (upper.length() > 3) {
result.add(upper);
}
}
С stream():
List<String> result = names.stream()
.map(String::toUpperCase)
.filter(s -> s.length() > 3)
.collect(Collectors.toList());
➡️ Читаемо, как SQL: "преобразуй → отфильтруй → собери".
✔️ Разберём подробнее:
1. `map()` — преобразование
.map(String::trim)
.map(String::toLowerCase)
🔄 Применяет функцию ко всем элементам. Тип может измениться.
2. `filter()` — отбор
.filter(s -> s.startsWith("a"))
❓ Оставляет только те элементы, которые удовлетворяют условию.
3. `collect()` — сборка результата
.collect(Collectors.toSet())
.collect(Collectors.joining(", "))
🧺 Собирает результат обратно в список, множество, строку и т.д.
📌 Реальный пример — фильтруем активных пользователей по возрасту:
List<User> users = getUsers();
List<String> activeAdults = users.stream()
.filter(User::isActive)
.filter(u -> u.getAge() >= 18)
.map(User::getName)
.collect(Collectors.toList());
➡️ Без лишних if, for и add() — код фокусируется на логике, а не на реализации.
🗣 Запомни: Цепочка map().filter().collect() — это про читаемый и декларативный код.
Не пиши как императивный робот, пиши как человек: что ты хочешь получить — а не как это сделать.6 682
🧪 Тесты с JUnit 5 — основные аннотации
JUnit 5 — это не просто
@Test. Он принёс гибкость, читаемость и мощные возможности для модульного тестирования.
Вот мини-шпаргалка по ключевым аннотациям, которые ты реально будешь использовать.
1. ✅ @Test — запуск теста
@Test
void shouldReturnTrueWhenInputIsValid() {
assertTrue(MyService.validate("test"));
}
➡️ Основная аннотация. Методы с ней — это тесты.
2. 🧱 @BeforeEach и @AfterEach — подготовка и очистка
@BeforeEach
void init() {
db.connect();
}
@AfterEach
void cleanup() {
db.disconnect();
}
➡️ Выполняются до и после каждого теста. Удобно для настройки окружения.
3. 🏗 @BeforeAll и @AfterAll — один раз на весь класс
@BeforeAll
static void globalSetup() {
System.out.println("Запускаем все тесты");
}
➡️ Статические методы, которые выполняются один раз перед/после всех тестов.
4. 🎯 @DisplayName — читаемое имя теста
@DisplayName("Должен вернуть true при корректном email")
@Test
void validEmailTest() {
assertTrue(EmailValidator.isValid("test@example.com"));
}
➡️ Название будет красиво отображаться в отчётах и IDE.
5. 🧪 @Nested — группировка тестов
@Nested
class WhenUserIsAdmin {
@Test
void shouldHaveFullAccess() { ... }
}
➡️Логическая структура внутри тест-класса. Удобно для сценариев.
6. ⚙️ @ParameterizedTest + @ValueSource — параметризованные тесты
@ParameterizedTest
@ValueSource(strings = {"admin", "user", "guest"})
void roleShouldNotBeNull(String role) {
assertNotNull(role);
}
➡️ Запускает один и тот же тест с разными значениями.
7. 🚫 @Disabled — временно отключить тест
@Disabled("Фича ещё не реализована")
@Test
void futureFeatureTest() {
fail("не должно запускаться");
}
➡️ Полезно, когда фича в разработке, а тест уже написан.
🗣 Запомни:JUnit 5 — это про читаемость, контроль и минимум лишнего кода. Используй аннотации не ради галочки, а чтобы тесты были понятны даже спустя полгода.6 682
😮 Добавлена новая база слитых курсов на 800ГБ:
Python:
https://t.me/+YxXMJRp6EwxjYmMy
Программирование:
https://t.me/+-5RBoQXVdONmOGEy
Графика и дизайн:
https://t.me/+dMZC3egGoQRkNjUy
Frontend и Web:
https://t.me/+Y5LpOYk_eZFjZDA6
6 682
⌨️ Generics и стирание типов
При компиляции все параметры обобщённых типов удаляются («стираются»), и на их место подставляется либо ограничивающий тип (
T extends Number → Number), либо Object.
Это нужно для совместимости с «сырыми» классами до появления Generics в Java 5.
Последствия стирания типов:
1️⃣ Нельзя создавать массивы обобщённого типа:
// Ошибка компиляции!
List<String>[] array = new List<String>[10];
2️⃣ Нельзя проверить во время выполнения, является ли объект именно List<String>:
List<String> list = List.of("a", "b");
if (list instanceof List<String>) { … } // компилятор не пропустит
3️⃣ Перегрузка методов с разными параметрами-дженериками конфликтует:
// Ошибка name clash: стираются оба в process(Collection)
void process(Collection<String> c) { … }
void process(Collection<Integer> c) { … }
Стиpaниe типов позволяет Java Generics не увеличивать размер байт-кода и оставаться совместимой с ранними версиями платформы, но налагает ограничения на проверку и создание обобщённых типов во время выполнения.6 682
Современная магистратура от Центрального университета
Хочешь развиваться в сфере ИТ и получить фундаментальные знания с практикой?
Поступай в магистратуру Центрального университета!
- 4 офлайн программы по востребованным направлениям ИТ
- Онлайн-программа по машинному обучению
- 300 мест с грантами до 1,2 млн руб.
- Вечерние занятия и учеба по выходным — удобно совмещать с работой
- Обучение по модели STEM-образования: на стыке науки, технологий и бизнеса
- Возможность стажировок и трудоустройства в ведущих компаниях
- Государственный диплом за 2 года
Магистратура в Центральном университете — это современный подход к образованию, сильный преподавательский состав и актуальные кейсы от индустрии.
Оставляй заявку на грант уже сейчас!
Подать заявку
#реклама 16+
apply.centraluniversity.ru
О рекламодателе
6 682
☕️Использование метода computeIfAbsent() из интерфейса Map.
Этот метод предлагает удобный способ вычисления и вставки значений в
Map, если они отсутствуют.
Пример кода с объяснением:
import java.util.HashMap;
import java.util.Map;
public class MapExample {
public static void main(String[] args) {
Map<String, Integer> wordLengths = new HashMap<>();
String word = "apple";
// Использование computeIfAbsent для вычисления и вставки значения в Map
wordLengths.computeIfAbsent(word, String::length);
// Вывод длины слова "apple", которая была вычислена и вставлена в Map
System.out.println("Длина слова apple: " + wordLengths.get(word));
}
}
🔒В этом примере мы используем метод computeIfAbsent() для wordLengths, чтобы вычислить и вставить длину слова "apple" в Map, если она отсутствует. Если значение уже присутствует, метод возвращает текущее значение.
Этот метод предоставляет удобный и эффективный способ добавления значений в мапу, если они отсутствуют, что может помочь упростить код и избежать лишних проверок на наличие ключей в Map.6 682
📱 Java Developer — мастхев для любого джависта
Канал Team Lead'a с полезными советами и практиками для Java-разработчиков:
➖ Книги, статьи, тесты
➖ Spring, Hibernate, Docker, SQL
➖ Алгоритмы, вопросы и задачи с собеседований
Присоединяйтесь: @java_tg
