Java: fill the gaps
Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк 🔥Тот самый курс по многопочке🔥 https://fillthegaps.ru/mt Комплименты, вопросы, предложения: @utki_letyat
Показати більше📈 Аналітичний огляд Telegram-каналу Java: fill the gaps
Канал Java: fill the gaps (@java_fillthegaps) у мовному сегменті Російська є активним учасником. На даний момент спільнота об'єднує 12 549 підписників, посідаючи 10 121 місце в категорії Технології та додатки та 52 862 місце у регіоні Росія.
📊 Показники аудиторії та динаміка
З моменту свого створення невідомо, проект продемонстрував стрімке зростання, зібравши аудиторію у 12 549 підписників.
За останніми даними від 07 червня, 2026, канал демонструє стабільну активність. Хоча за останні 30 днів спостерігається зміна кількості учасників на -46, а за останні 24 години на 0, загальне охоплення залишається високим.
- Статус верифікації: Не верифікований
- Рівень залученості (ER): Середній показник залученості аудиторії становить 34.72%. Протягом перших 24 годин після публікації контент зазвичай збирає N/A% реакцій від загальної кількості підписників.
- Охоплення публікацій: В середньому кожен допис отримує 0 переглядів. Протягом першої доби публікація в середньому набирає 0 переглядів.
- Реакції та взаємодія: Аудиторія активно підтримує контент: середня кількість реакцій на один пост – 0.
- Тематичні інтереси: Контент зосереджений навколо ключових тем, таких як redis, hashmap, linkedhashmap, индекс, фича.
📝 Опис та контентна політика
Автор описує ресурс як майданчик для висловлення суб'єктивної думки:
“Привет! Меня зовут Диана, и я занимаюсь разработкой с 2013. Здесь пишу просто и понятно про джава бэк
🔥Тот самый курс по многопочке🔥
https://fillthegaps.ru/mt
Комплименты, вопросы, предложения: @utki_letyat”
Завдяки високій частоті оновлень (останні дані отримано 08 червня, 2026), канал підтримує актуальність та високий рівень охоплення публікацій. Аналітика показує, що аудиторія активно взаємодіє з контентом, що робить його важливою точкою впливу в категорії Технології та додатки.
public void do() {
File f=new File("t.txt");
// Создаём объект File, ресурс "t.txt" теперь наш
// что-то делаем
}
// вышли из метода: объект f уже не нужен, ресурс "t.txt" освобождается
RAII легко реализовать в С++. В конструкторе пишем логику "открытия" ресурса, а в деструкторе - "закрытия". Конструктор и деструктор явно прописываются, поэтому ЖЦ объекта и ресурса под контролем.
В java так не получится. Деструктор выполнится неизвестно когда, а ресурс - штука ценная. Поэтому в java нужно явно вызвать метод закрытия. В стандартных библиотеках это close().
В java 7 появилась специальная конструкция для ресурсов:
try (PrintWriter writer = new PrintWriter(…)) {
// что-то делаем
}
Ресурс реализует интерфейс AutoCloseable, и после завершения блока для него вызовется close(). try-with-resources считается java реализацией RAII.
Но такой формат не идеален. Внутри try всегда определяется новый объект. Когда ресурсов два и больше, код становится громоздким:
try (DatagramChannel udpServer = …;
Selector selector = …) {
// …
}
В java 9 в блок try можно передать переменные:
DatagramChannel udpServer = …;
Selector selector = …;
try (udpServer;selector) {
// …
}
С одной стороны это удобно. Код выглядит приятно.
С другой - после try остаются переменные с закрытыми ресурсами. Теперь нельзя сказать, что java реализует RAII.
Ну и ладно, никто не расстроился🙂 Языки разные, и классно замечать, как по-разному в них реализуются идеи, и как они меняются с течением времени.git stash save "stash name"В IDEA: VCS → Git → Stash Changes... Вернуть изменения на место: 🔸git stash apply "stash name" и оставить stash в локальном репозитории 🔸git stash pop "stash name" и удалить стэш В IDEA: VCS → Git → Unstash Changes... Что важно: ✅ Сохраняются ВСЕ текущие изменения в ветке ✅ Обратно применяются ВСЕ изменения в стэше ✅ Изменения хранятся в локальном git репозитории Shelve Удобная фича IDEA для сохранения части изменений: VCS → Shelve Changes... Галочками отмечаем, что сохранить. Чтобы вернуть обратно: Вкладка Git (Alt + 9 или найдите внизу) → Shelve. Отмечайте, какие изменения применить к коду. ✅ Можно выбрать, что сохранять ✅ Можно указать, что восстановить ✅ Изменения хранятся в локальном IDEA проекте
public final class State extends Enum {
public static final State NEW;
public static final State VALIDATED;
// init блок
State() {...}
// static блок
}
Возникла проблема. Перед вызовом конструктора надо закончить со статическими полями. А статические поля - экземпляры этого же класса. Замкнутый круг.
В такой ситуации JVM создаёт экземпляры NEW и VALIDATED перед статическими блоками. Получается такой порядок:
1️⃣ Создаём экземпляр State NEW:
▫️блок инициализации S-Init
▫️конструктор S-Constr
2️⃣ Повторяем тот же процесс для VALIDATED
3️⃣ Выполняем статический блок S-Static
Поэтому правильный ответ - G:
▫️enum NEW(Init-Constr)
▫️enum VALIDATED(Init-Constr)
▫️enum-Static
▫️объект User (Init-Constr)if (state == UserState.NEW) {…}
2️⃣ Паттерн Singleton
Вообще синглтон - антипаттерн и антитренд. Если без него никак - рассмотрите вариант с enum. Если вы склонны к риску, можно сделать изменяемые поля.
✅ Может быть несколько объектов в рамках одного enum
✅ Доступ из любого места в коде
✅ Ленивая инициализация
3️⃣ Паттерн State
Более продвинутый вариант, чем "набор констант". Здесь фокус на данных: используются связанные значения, а не элемент enum сам по себе.
Пример: в статус пользователя вносим дополнительные поля - необходимость подтверждения личности и максимальный размер скидки:
enum UserState {
NEW(true, 10),
VALIDATED(false, 25),
FRAUD(true, 0);
boolean needConfirmation;
int maxDiscount;
}
4️⃣ Паттерн Strategy
Здесь фокус на разнице в поведении. Абстрактный метод переопределяется для каждого экземпляра:
NEW { boolean check(Order){…}},
VALIDATED { boolean check(Order){…}};
abstract boolean check(Order order)
✅ Подойдёт для алгоритмов, конвертеров, сортировок
✅ Простая иерархия, всё в одном классе
✅ Список всех значений доступен через values()
😐 Весь код в одном файле. Не всегда удобно
❌ Сложно связать с другими объектами
❌ Нарушается принцип open for extension but closed for modification
Получается специфическая альтернатива полиморфизму, но иногда ок.
Enum - не просто набор констант. Инструмент своеобразный, но полезно знать и такие реализации паттернов. Чем шире арсенал разработчика, тем выше шанс найти подходящее решение.public final class Planet extends Enum {
public static final Planet EARTH;
public static final Planet MARS;
}
Полноценные классы c конструкторами, методами, полями и статическими элементами. У экземпляров есть состояние и определённое поведение.
Но есть нюансы:
🔸 Суперкласс Enum
От суперкласса Enum наследуются методы name(), ordinal() и статический метод values().
name() возвращает имя переменной, ordinal() - порядковый номер в списке. На практике эти методы достаточно бесполезны.
Метод values() используется чаще и возвращает массив всех объектов. Можно пройтись по нему в цикле:
for (Planet p : Planet.values()) {…}
или через Stream API:
Arrays.stream(Planet.values()).forEach(…)🔸 Интерфейсы суперкласса Enum реализует три интерфейса: Comparable, Serializable, Constable. Первые два всем знакомы. Интерфейс Constable определяет методы для размещения объектов в пуле констант внутри JVM. 🔸 Создание экземпляров Этим занимается JVM на старте приложения. Экземпляры енума создаются через приватный конструктор, недоступный вне енума. 🔸 Поля Указываются для каждого экземпляра, инициализируются в конcтрукторе:
public enum Planet {
MARS(3389),
EARTH(6371);
int radius;
Planet(int radius) {
this.radius = radius;
}
}
🔸 Два типа методов
▫️Обычные
public int getRadius()
Используется для геттеров и простых вычислений.
В теории можно сделать set* метод и поменять поле у любого экземпляра. Но на практике так никто не делает. Когда объект доступен из любого места системы, то проще жить, если он неизменяемый.
▫️Абстрактные
Каждый экземпляр определяет свою реализацию:
public enum Planet {
MARS {
int distanceFrom(int) {…}
},
EARTH {
int distanceFrom(int) {…}
};
abstract int distanceFrom(int);
}
🔸 Наследование
Любой enum - это final класс с уже определённым суперклассом. Единственный шанс встроить enum в иерархию - добавить для него интерфейс.
Иногда это удобно. Если у енумов и классов один интерфейс, то с ними можно работать через один метод:
interface SpaceObject
enum Planet implements SpaceObject
class Meteor implements SpaceObject
public void getInfo(SpaceObject so)-XX:+UnlockExperimentalVMOptions -XX:+EnableJVMCI -XX:+UseJVMCICompiler map.compute(key,(key,value)->value+1)
Покрыта ветка В. Если элемента с ключом key нет, то в качестве value будет null. Велика вероятность NullPonterException
🔹 map.computeIfPresent(key,(key,value)->value+1)
Покрыта ветка Б. Нет элемента - ничего не делаем
🔹 map.merge(key,defaultValue,(oldValue,newValue) -> oldValue+1);
Покрывает ветки А и В:
▫️ Если элемента нет, добавляем (key, default)
▫️ Если элемент есть, обновляем по правилу
Итого, как сценарные ветки покрыты методами:
Ветка А: merge
Ветка Б: computeIfPresent
Ветка В: merge, compute
Все сценарии покрываются двумя методами - computeIfPresent и merge.
Метод compute в этом случае избыточен. Избыточность - ок, если метод добавляет удобства и не увеличивает вероятность ошибок. В случае compute это не так, так как появляется вероятность получения NPE.
На этом небольшом примере видно, как проверить дизайн нового API. Методы должны быть удобными, понятными и не заставлять разработчиков запоминать особые случаи.
Вже доступно! Дослідження Telegram за 2025 — головні інсайти року 
