ch
Feedback
Java | Фишки и трюки

Java | Фишки и трюки

前往频道在 Telegram

Java: примеры кода, интересные фишки и полезные трюки Купить рекламу: https://telega.in/c/java_tips_and_tricks ✍️По всем вопросам: @Pascal4eg Менеджер по рекламе: @shmyzna

显示更多
6 953
订阅者
-324 小时
-27
+630
帖子存档
JDBC 🆚 Hibernate: как Java работает с базами — и чем это тебе грозит Java умеет работать с БД как вручную (через JDBC), так и “по-умному” (через Hibernate/JPA). Один путь — контроль и боль. Второй — магия и её последствия. Разберём всё по фактам, на живых примерах 👇 🔌 JDBC — низкоуровневый доступ через SQL
Connection conn = DriverManager.getConnection(url, user, pass);
PreparedStatement stmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
stmt.setInt(1, 42);
ResultSet rs = stmt.executeQuery();

while (rs.next()) {
    System.out.println(rs.getString("name"));
}
🟢 Всё вручную: от подключения до маппинга. 🟢 Полный контроль, но каждый чих — в 5 строк. 🟢 Если ты решил добавить JOIN — добро пожаловать в SQL-приключения. 🏗 Hibernate / JPA — ORM и сущности
@Entity
public class User {
    @Id
    private Long id;
    private String name;
}
User user = entityManager.find(User.class, 42L);
🟢 SQL скрыт под капотом, данные — это Java-объекты. 🟢 Быстро, декларативно, красиво. 🟢 Но ты больше не контролируешь, что именно улетает в базу. 💥 Пример боли: Lazy vs Eager
@Entity
public class Post {
    @ManyToOne(fetch = FetchType.LAZY)
    private User author;
}
Post post = postRepo.findById(1L).get();
System.out.println(post.getAuthor().getName()); // 💣 LazyInitializationException
🟢 Если сессия закрыта — Hibernate не подгрузит данные. 🟢Работает только внутри транзакции. 🟢 Или делай JOIN FETCH, или не забывай про открытые сессии. 🛠 Spring + JPARepository — удобный уровень
public interface UserRepo extends JpaRepository<User, Long> {
    List<User> findByName(String name);
}
➡️ Никаких SQL, методы создаются из названия. ➡️ CRUD, пагинация, фильтры — всё из коробки. ➡️ Но если нужен ручной SQL — Spring Data позволяет это тоже:
@Query("SELECT u FROM User u WHERE u.name LIKE %:name%")
List<User> search(@Param("name") String name);
⚙️ JdbcTemplate — между ручным и магическим
List<User> users = jdbcTemplate.query(
    "SELECT * FROM users",
    (rs, rowNum) -> new User(rs.getLong("id"), rs.getString("name"))
);
➡️ Ты пишешь SQL, но не паришься с ResultSet. 🟢 Оптимально для кастомных запросов. 🧪 Тестирование — через @DataJpaTest и H2
@DataJpaTest
class RepoTest {
    @Autowired UserRepo repo;

    @Test
    void testSave() {
        repo.save(new User("Test"));
        assertTrue(repo.findByName("Test").size() > 0);
    }
}
➡️ H2 работает в памяти, быстро поднимается и убивается. 🟢 Подходит для unit+integration тестов одновременно. 🗣️ Запомни: JDBC — как нарезать салат вручную: аккуратно, но долго. Hibernate — как блендер: быстро, но иногда не туда. Выбирай по задаче, а не по вкусу архитектора.

Регистрируйтесь на Yandex Ecom Open Air 8 августа Море инсайтов для бизнеса, музыкальный open-air, лекции и нетворкинг. Участие бесплатно! Зарегистрироваться #реклама 18+ ecomfest.ru О рекламодателе

☕️ Установка JDK и IDE.
В этом видео автор простым и понятным языком демонстрирует установку Java с нуля — от загрузки JDK до настройки среды разработки (IDE). Всё показано пошагово: выбор инструментария, установка, проверка работоспособности.Это отличный старт, если ты только начинаешь изучать Java и хочешь настроить всё правильно с самых основ.
🤩 Java Фишки и трюки || #Видео

🧪 Создание объекта без конструктора — это реально В Java обычно new вызывает конструктор. Но можно создать объект, вообще не вызывая ни один конструктор. Даже private, даже если он кидает исключения. Это работает через ☠️ Unsafe или ✔️ Objenesis. ☠️ Unsafe: объект без жизни
class User {
    private User() {
        throw new RuntimeException("нельзя вызывать");
    }
}

Unsafe unsafe = ...;
User user = (User) unsafe.allocateInstance(User.class);
➡️ Объект создан. Конструктор не сработал. ➡️ Все поля — нули, даже final. Ты просто получил кусок памяти под User, но без инициализации.Objenesis: библиотека для этого
Objenesis objenesis = new ObjenesisStd();
User user = objenesis.newInstance(User.class);
➡️ Тоже создаёт объект без конструктора. ➡️ Работает на всех JVM, без хака Unsafe. ➡️ Поддерживается, используется в Spring, Mockito, Kryo. 📦 Maven-зависимость:
<dependency>
  <groupId>org.objenesis</groupId>
  <artifactId>objenesis</artifactId>
  <version>3.3</version>
</dependency>
📛 Где это используют Hibernate, Jackson, Kryo, Mockito — создают объекты из JSON или прокси без вызова конструктора. Ты можешь сделать то же:
class Secret {
    private final int x = 42;
    private Secret() {
        throw new IllegalStateException("нельзя");
    }
}

Secret s = (Secret) unsafe.allocateInstance(Secret.class);
System.out.println(s.x); // 0, даже final не работает
➡️ Конструктор не вызвался, даже final сброшен. 🗣 Запомни:Ты можешь создать любой объект — даже если конструктор кидает ошибку. Просто Unsafe.allocateInstance(Class) или objenesis.newInstance(Class). Но инициализировать поля придётся самому.

🚀Хотите создавать приложения на Android и стать востребованным разработчиком? Присоединяйтесь к курсу «Android Developer» и
🚀Хотите создавать приложения на Android и стать востребованным разработчиком? Присоединяйтесь к курсу «Android Developer» и научитесь разрабатывать масштабируемые приложения на Kotlin, работать с Jetpack Compose и Android SDK, использовать популярные фреймворки Dagger2, Hilt, RxJava, а также разбираться в принципах CI/CD, Docker и Kubernetes. Вы сможете проектировать многомодульную архитектуру, создавать UI и анимировать экраны, интегрировать базы данных, а также научитесь тестировать приложения с помощью Espresso и JUnit. После курса вас ждёт реальное портфолио и диплом OTUS, который ценится в крупных компаниях! ⚡️Старт 30 июля, успевайте оставить заявку и получить скидку на обучение: https://otus.pw/MRDY/ Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

🧩 Marker + Default methods: интерфейсы как конфигурация, без аннотаций и свитчей Ты можешь использовать интерфейсы не как API, а как декларативную конфигурацию — через маркер + дефолтные методы. Без if-else, без флагов, без switch. 📛 Маркер как флаг
public interface Debuggable {} // пустой интерфейс
➡️ Никакой логики, просто метка. Если класс его реализует — значит, он отлаживаемый.
public class Service implements Debuggable {}
💡 Теперь достаточно instanceof:
void log(Object o) {
    if (o instanceof Debuggable) {
        System.out.println("🐞 Включаем отладку");
    }
}
➡️ Никаких .isDebug(), никаких аннотаций — только тип. 🛠 Дефолтные методы — поведение по умолчанию
public interface HasTimeout {
    default int getTimeout() {
        return 1000; // мс
    }
}
Ты получаешь “конфигурацию по умолчанию”, которую можно переопределить:
public class FastRequest implements HasTimeout {
    @Override
    public int getTimeout() {
        return 100;
    }
}

public class NormalRequest implements HasTimeout {
    // будет 1000 по умолчанию
}
void send(HasTimeout req) {
    System.out.println("⌛️ Таймаут: " + req.getTimeout());
}
➡️ Без config-файлов, без if (instanceof) — всё в типе. 📦 Конфигурация как набор интерфейсов
public interface RequiresAuth {
    default boolean isAuthRequired() {
        return true;
    }
}

public interface ReturnsJson {
    default String contentType() {
        return "application/json";
    }
}
➡️ И теперь просто пишешь:
public class ApiCall implements RequiresAuth, ReturnsJson {}
void handle(Object call) {
    if (call instanceof RequiresAuth auth && auth.isAuthRequired()) {
        System.out.println("🔐 Проверка токена");
    }
    if (call instanceof ReturnsJson rj) {
        System.out.println("📤 JSON-ответ: " + rj.contentType());
    }
}
➡️ Тип сам диктует поведение. Без логики — просто наличие интерфейса. 📚 Даже enum можно конфигурировать
public interface Critical {}

public enum Action implements Critical {
    DELETE_ALL, RESET_DB
}
void execute(Enum<?> action) {
    if (action instanceof Critical) {
        System.out.println("🚨 ВНИМАНИЕ: опасная операция");
    } else {
        System.out.println("✅ Безопасно");
    }
}
➡️ Enum + интерфейс = мощная типовая декларация. 🗣️ Запомни: Marker + Default methods = тип как конфигурация. Ты пишешь код, который читает сам себя. Поведение не через данные, а через тип.Меньше if, меньше флагов, больше ясности.

❓ Как создавать смарт-контракты и писать свой токен на Solidity? 👉 На открытом уроке 31 июля в 20:00 МСК мы разберём основы
❓ Как создавать смарт-контракты и писать свой токен на Solidity? 👉 На открытом уроке 31 июля в 20:00 МСК мы разберём основы блокчейна и смарт-контрактов, а также познакомим вас с возможностями тестирования проектов. Вы сможете написать свой первый токен на Solidity и получите чёткое представление о том, как блокчейн работает на практике. Урок будет полезен всем новичкам, которые хотят быстро погрузиться в мир блокчейна, а также программистам с опытом работы с языками, готовым освоить смарт-контракты. 🎁 Посетите вебинар и получите специальное предложение на большой курс «Solidity Developer». 👉 Для участия зарегистрируйтесь https://otus.pw/M0LM/ Реклама. ООО «Отус онлайн-образование», ОГРН 1177746618576

☕️ JDK 24 ускоряет Java-бэкенд: от виртуальных потоков до операций с FFM Нашёл одну свежую и реально интересную статью — обзо
☕️ JDK 24 ускоряет Java-бэкенд: от виртуальных потоков до операций с FFM Нашёл одну свежую и реально интересную статью — обзор Performance Improvements in JDK 24 от Inside.java (март 2025). В ней рассказывается о конкретных улучшениях, которые уже влияют на скорость приложений. В статье вы найдёте: 📌 Оптимизация «bulk operations» в Foreign Function & Memory API — быстрее копирование и заполнение сегментов 📌 MergeStore в JIT — меньше операций записи, выше скорость работы с массивами 📌 Ускоренный startup через скрытые классы для конкатенации строк 📌 +27 % ускорения хеширования с SHA‑3 📌 Доработки виртуальных потоков: снятие pinning, лучшая синхронизация 📌 Что полезного для разработчиков: всё это работает «из коробки» — без переписывания кода 📌 Как это помогает писать код лучше: меньше задержек, быстрее прод, внимание разработчика уходит в логику, а не оптимизацию ➡️ Читайте и наслаждайтесь 🗣️ JDK‑24 — это не просто новая версия, а реальный прирост скорости для вашего продакшена. 🤩 Java Фишки и трюки || #Cтатья

🧨 Unsafe в Java: прямой доступ к памяти (и да — это реально работает) Java — безопасный язык, пока ты не подключаешь Unsafe. Это внутренний API из JDK, который даёт доступ к памяти как в C: ты можешь читать, писать, аллоцировать и даже обойти конструкторы. Без всяких JVM-защит. ⛔ Не использовать в проде без необходимости. Но как концепт — огонь. 📦 Получаем доступ к Unsafe (через костыль)
Field f = Unsafe.class.getDeclaredField("theUnsafe");
f.setAccessible(true);
Unsafe unsafe = (Unsafe) f.get(null);
➡️ Это приватное поле, поэтому нужен рефлекс. С Java 12 и выше понадобится --add-opens, но в старых версиях работает напрямую. 💥 Аллокация памяти вручную
long address = unsafe.allocateMemory(8); // 8 байт
unsafe.putLong(address, 123456789L);     // запись
long value = unsafe.getLong(address);    // чтение

System.out.println(value); // 123456789

unsafe.freeMemory(address); // ручной free
➡️ Как malloc/free. Память вне кучи (off-heap), GC её не видит. 🧬 Доступ к полям объекта по смещению
class Demo {
    private int secret = 42;
}

Demo d = new Demo();
Field field = Demo.class.getDeclaredField("secret");
long offset = unsafe.objectFieldOffset(field);

unsafe.putInt(d, offset, 99); // меняем приватное поле

System.out.println(unsafe.getInt(d, offset)); // 99
➡️ Меняем приватные поля БЕЗ сеттеров и даже без setAccessible. 🚫 Обход конструктора: создаём объект без new
class NoConstructor {
    private NoConstructor() {
        throw new RuntimeException("Don't call me");
    }
}

NoConstructor obj = (NoConstructor) unsafe.allocateInstance(NoConstructor.class);
System.out.println(obj);
➡️ JVM не вызывает конструктор вообще. Объект появляется из воздуха. 🧠 Прямое управление массивами
int[] arr = new int[10];
long base = unsafe.arrayBaseOffset(int[].class);
int scale = unsafe.arrayIndexScale(int[].class);

unsafe.putInt(arr, base + scale * 5, 99); // пишем в arr[5]
System.out.println(arr[5]); // 99
➡️ Как pointer arithmetic в C. У тебя есть offset и шаг (scale). ✔️ Используй Unsafe, чтобы: 🟢 делать off-heap кэш/пулы 🟢 изменять приватные данные в рантайме 🟢 писать кастомные структуры данных 🟢 встраивать C-подобные трюки в Java 🗣️ Запомни: Это выход за пределы JVM-санбокса. Но иногда он даёт то, что невозможно сделать иначе. Unsafe — это как ядро Java-хакерства. У него огромная сила, но и риск.

Айтишники, это вам — в телеграм есть комьюнити по каждому направлению в IT Там есть буквально всё: чаты для общения, тонны ма
Айтишники, это вам — в телеграм есть комьюнити по каждому направлению в IT Там есть буквально всё: чаты для общения, тонны материала(книги, курсы, ресурсы и гайды), свежие новости и конечно же мемы Выбирайте своё направление: 💩 Frontend 🐍 Python 🐧 Linux 👩‍💻 С/С++ 👩‍💻 C# 🤔 Хакинг & ИБ 📱 GitHub 🖥 SQL 👩‍💻 Сисадмин 🤟 DevOps ⚙️ Backend 🖥 Data Science 🧑‍💻 Java 🐞 Тестирование 🖥 PM / PdM 👩‍💻 GameDev 🧑‍💻 Golang 👣 Rust 🧑‍💻 PHP 💻 WebDev 🖥 Моб. Dev 🖥Анали.(SA&BA) 👩‍💻 Дизайн 🖥 Нейросети 💛 1C 🤓 Книги IT ➡️ Сохраняйте в закладки

🧰 Маппинг Enum по String без if/switch: делаем Map Классика: приходит строка "ACTIVE" — надо получить Status.ACTIVE. Но вместо кучи if или switch — строим быстрый и красивый Map-мэппинг, который работает за O(1) и не ломается при добавлении новых enum. Вот как это сделать правильно 👇 🟢 Enum с кодом
public enum Status {
    ACTIVE("active"),
    BLOCKED("blocked"),
    DELETED("deleted");

    private final String code;
    Status(String code) { this.code = code; }
    public String getCode() { return code; }
}
➡️ Мы явно задали code, который будет использоваться для маппинга (например, из JSON, БД или UI). 🟢 Создаём Map один раз
public class StatusMapper {
    private static final Map<String, Status> CODE_MAP = Arrays.stream(Status.values())
        .collect(Collectors.toMap(Status::getCode, Function.identity()));

    public static Status fromCode(String code) {
        return CODE_MAP.get(code);
    }
}
➡️ При первом запуске строим Map<String, Status>, где ключ — это status.getCode(), а значение — сам enum. 🧪 Использование:
Status status = StatusMapper.fromCode("active");
System.out.println(status); // ACTIVE
➡️ Работает мгновенно и безопасно. Без цепочек if, без null, без ошибок при добавлении новых значений. 🛡 Добавим защиту от невалидных значений:
public static Status fromCode(String code) {
    Status result = CODE_MAP.get(code);
    if (result == null) {
        throw new IllegalArgumentException("Unknown status: " + code);
    }
    return result;
}
➡️ Код теперь fail-fast. Любое неожиданное значение сразу бросит ошибку — удобно в API и при валидации. 🗣️ Запомни: Enum.name() и Enum.toString() — не для бизнес-логики. Маппинг через Map — самый быстрый и читаемый способ.

Жара в IT! Теперь популярные языки программирования можно легко выучить по гайдам в картинках Бесплатные инструменты, полезны
+4
Жара в IT! Теперь популярные языки программирования можно легко выучить по гайдам в картинках Бесплатные инструменты, полезные ресурсы, а также советы и задачки. Выбирай нужное направление и учись не напрягаясь: 👩‍💻 Linux Ninja 🖥 CodHub | Курсы IT 📱 Python | Программирование 😷 Hacking | Кибербезопасность ⚙️ Webdev | Backend & Frontend 🖥 Программирование по мемам

⚡️ Static Initializer Hack в Java — выполняем код при загрузке класса Java даёт способ выполнить код один раз, ещё до создания объекта. Это называется static initializer — и с ним можно делать настоящие фокусы 👇 🔁 Что это вообще такое Когда JVM загружает класс — выполняются все static-блоки, даже если ты не создавал ни одного объекта. Это можно использовать для: 🟢 регистрации классов 🟢 скрытой инициализации 🟢 запуска кода без main() 🟢 взлома "одиночек" или подмены поведения 📦 Простой пример static-блока
public class Hello {
    static {
        System.out.println("Загрузка Hello");
    }

    public static void main(String[] args) {
        System.out.println("main()");
    }
}
➡️ Вывод:
Загрузка Hello
main()
🟢 Сначала сработал static-блок, потом вызвался main. 💣 Выполнение кода без main()
public class RunOnce {
    static {
        System.out.println("Код запустился без main()");
        System.exit(0); // JVM завершится
    }
}
🟢 При запуске RunOnce.class — код выполнится, и main() даже не потребуется. 🧠 Применение: регистрация классов
interface Plugin {
    void run();
}

class Registry {
    static List<Plugin> plugins = new ArrayList<>();
    static void register(Plugin p) {
        plugins.add(p);
    }
}

public class PluginA implements Plugin {
    static {
        Registry.register(new PluginA());
    }

    public void run() {
        System.out.println("Плагин A запущен");
    }
}
🟢 Просто загрузив PluginA, ты уже зарегистрировал его — без явного вызова конструктора или методов. 🧪 Хак с подменой поведения
class Evil {
    static {
        System.setSecurityManager(null); // отключаем защиту
    }
}
🟢 Опасная штука — используется при обходе sandbox'а или во взломе. Подгружаешь Evil.class, и твой код внезапно без ограничений. 💬 Хочешь пост про Unsafe, Objenesis или про bytecode-инъекции? Пиши тему — сделаем с практикой. 🗣️ Запомни:Если ты понимаешь когда и зачем срабатывает static-блок — ты уже на шаг ближе к JVM-магию ☄️

👨‍💻Ищем Backend и ML разработчиков, удалёнка, платим много! Специально для Вас, собираем лучшие вакансии. Только вакансии с прямыми контактами в Telegram! 👩‍💻 Java 👣 GoLang 👩‍💻 Python 🖼️ PHP 👩‍💻 Node.js 🤖 ML & Data Science 👩‍💻 C# Подпишись чтобы не упустить свой шанс получить лучший оффер!

⌨️ Maven. Фазы и команды Maven использует жизненный цикл сборки, который делится на несколько фаз. Фазы определяют последовательность задач, которые Maven выполняет для сборки и управления проектом. Основные фазы жизненного цикла Maven включают: 1️⃣ validate – Проверяет, что проект правильный и вся необходимая информация указана. 2️⃣ compile – Компилирует исходный код проекта. 3️⃣ test – Запускает тесты (обычно с использованием JUnit или TestNG) и проверяет, что они проходят успешно. 4️⃣ package – Собирает скомпилированный код и пакует его, например, в JAR или WAR-файл. 5️⃣ verify – Проверяет собранные артефакты и результаты тестов. 6️⃣ install – Устанавливает пакет в локальный репозиторий для использования как зависимость в других проектах. 7️⃣ deploy – Отправляет финальный пакет в удаленный репозиторий для использования в других проектах или на сервере. Основные команды Maven: ✔️ mvn clean – Удаляет папку target, очищая проект от предыдущих сборок. ✔️ mvn compile – Компилирует исходный код проекта. ✔️ mvn test – Запускает тесты. ✔️ mvn package – Пакует скомпилированный код в конечный артефакт (обычно JAR или WAR). ✔️ mvn install – Устанавливает артефакт в локальный репозиторий. ✔️ mvn deploy – Деплоит артефакт в удаленный репозиторий. ✔️ mvn site – Генерирует документацию проекта на основе кода и зависимостей. Фазы выполняются последовательно, то есть если вы запускаете команду mvn install, Maven автоматически пройдет через все предыдущие фазы – от validate до install. Примеры команд: ✔️ mvn clean install – очищает проект, компилирует, тестирует и устанавливает артефакт в локальный репозиторий. ✔️ mvn package -DskipTests – собирает проект в артефакт, пропуская тесты. #java #Maven

🧠 Rate Limiter на Java без Spring — с нуля, по шагам, с мозгами Когда у тебя API, бот, сервер или утилита — нужно ограничивать частоту запросов, чтобы никто не зафлудил систему. Решение — Rate Limiter. Ни Spring, ни Guava не нужны. Всё делаем на чистом Java. 📁 Шаг 🔢: создаём лимитер с окном по времени Идея простая: мы храним время всех недавних запросов и выкидываем те, что вышли за окно (например, 10 секунд назад).
class RateLimiter {
    private final int limit;
    private final long windowMs;
    private final Deque<Long> timestamps = new ArrayDeque<>();

    public RateLimiter(int limit, long windowSeconds) {
        this.limit = limit;
        this.windowMs = windowSeconds * 1000;
    }

    public synchronized boolean allow() {
        long now = System.currentTimeMillis();
        // Удаляем старые запросы
        while (!timestamps.isEmpty() && now - timestamps.peek() > windowMs) {
            timestamps.poll();
        }
        // Проверка лимита
        if (timestamps.size() < limit) {
            timestamps.add(now);
            return true;
        }
        return false;
    }
}
➡️ Здесь limit — количество запросов, windowSeconds — время в секундах. Всё хранится в памяти. Работает моментально, идеально для локального контроля. 📁 Шаг 🔢: подключаем к логике запроса Представим, у тебя HTTP-сервер или обработчик:
RateLimiter limiter = new RateLimiter(5, 10); // 5 запросов на 10 сек

public void handleRequest() {
    if (limiter.allow()) {
        System.out.println("✅ Запрос принят");
    } else {
        System.out.println("❌ 429 Too Many Requests");
    }
}
➡️ За секунду можно накидать 5 успешных запросов, шестой — будет заблокирован. Через 10 секунд — снова 5 доступных. 📁 Шаг 🔢: делаем лимиты на пользователя / IP / ключ Чтобы не глобально, а по каждому клиенту — оборачиваем RateLimiter в Map.
Map<String, RateLimiter> userLimits = new ConcurrentHashMap<>();

public boolean allowRequest(String userId) {
    userLimits.putIfAbsent(userId, new RateLimiter(10, 30));
    return userLimits.get(userId).allow();
}
➡️ Теперь у каждого клиента — свой лимит. IP → лимитер, токен → лимитер, логин → лимитер. 📁 Шаг 🔢: многопоточность и защита
Так как у нас ConcurrentHashMap и synchronized внутри лимитера — решение уже потокобезопасное. Можно сразу использовать в многопоточных веб-приложениях или TCP-серверах.
📁 Шаг 🔢: нагрузочное тестирование Вот что будет, если послать много запросов:
for (int i = 0; i < 20; i++) {
    boolean ok = limiter.allow();
    System.out.println(i + " -> " + (ok ? "✅" : "❌"));
    Thread.sleep(1000);
}
➡️ Первые 5 — пройдут. Потом 10 ❌. Потом снова пойдут ✔️ по мере освобождения окна. Всё по-честному. 🗣️ Запомни:Rate Limiter — это простая логика, но если её нет — ты труп под первым же флотом запросов.Лимиты = защита = стабильность. Не жди DDoS, внедряй заранее.

📚 Physics.Math.Code — крупнейшее русскоязычное сообщество с лучшим контентом для физиков, математиков и разработчиков. 🎥 Учебные фильмы — фильмы по физике, математике, программированию, технологиях, химии, биологии. Самые интересные видео для развития. 👾 Эпсилон — канал с книгами по информационной безопасности, IT технологиям, робототехнике и достижениям Computer Science. 💡 Репетитор IT men — блог с заметками преподавателя по физике, математике, IT, железе. Разборы интересных задач, рассуждения о науке, образовании и методах обучения. 🧬 Chemistry.Biology.Anatomy — канал для химиков, биологов и медиков. ⚙️ Техника .TECH — эстетика технологий различных времен

⚙️ Java 25: долгожданный LTS и революция в многопоточности Java не стоит на месте: версия 25 выходит уже этой осенью и принес
⚙️ Java 25: долгожданный LTS и революция в многопоточности Java не стоит на месте: версия 25 выходит уже этой осенью и принесёт не просто косметические изменения, а реально новые возможности для удобного, быстрого и современного кода. Если вы считали Java «тяжеловесом» — самое время пересмотреть взгляд! В статье вы найдёте: 📌 Краткий разбор фич Java 25: pattern matching для примитивов, structured concurrency, compact object headers 📌 Как Project Loom меняет подход к потокам в реальных приложениях 📌 Что дают Value Types и Scoped Values для читаемости и производительности 📌 Новые инструменты профилирования: CPU‑time в JFR, AOT‑profiling и др. 📌 Рекомендации, как безболезненно перейти на новую версию ➡️ Читайте и наслаждайтесь 🗣️ Java больше не просто классика: это современный, лаконичный и быстрый инструмент для продвинутой разработки. 🤩 Java Фишки и трюки || #Cтатья

📢 Выходцы из Jetbrains запилили годноту для Java/Kotlin-разработчиков. Стартап называется ❇️ Explyt. Они только что выкатили
📢 Выходцы из Jetbrains запилили годноту для Java/Kotlin-разработчиков.   Стартап называется ❇️ Explyt. Они только что выкатили мощный релиз.  Вкратце: это плагин в IDE, который сам генерирует тесты с интересными возможностями:  ✔️ Vibe debugging. За счет интеграции с IDE, плагин собирает данные по исполнению программы и генерирует тест по этим данным, что экономит время на тестировании и отлавливает ошибки на 80-90% (!)  ✔️ Агентский режим. Ассистент, который живёт в проекте и следит за покрытием, сам находит незакрытые места и предлагает тесты. Работает в фоне, как часть команды.  👉 Кому интересно - вот ссылка на релиз и установку плагина

☕️ Как работает Lombok под капотом. Lombok кажется магией: пишешь @Getter, @Builder, @Slf4j — и бац, всё работает. Но на самом деле он не добавляет методы во время выполнения. Всё происходит на этапе компиляции, и ты даже можешь это увидеть. 🟢 Что реально происходит с @Getter
@Getter
public class User {
    private String name;
}
➡️ Во время компиляции Lombok встраивает в AST (абстрактное синтаксическое дерево) метод:
public String getName() {
    return this.name;
}
➡️ То есть ты этого в коде не видишь, но javac уже получил готовый getName(), как будто ты сам его написал. 🟢 Где именно это происходит
Lombok использует Javac-плагины и работает как annotation processor. Он подключается в javac через SPI (Service Provider Interface) и внедряется в процесс разбора исходного кода — до того, как он станет байткодом.
➡️ Это не runtime, а compile-time магия. 🟢 Почему это работает в IDE
IntelliJ IDEA и Eclipse поддерживают Lombok через плагины. Они умеют подхватывать изменения AST от Lombok, и даже подсвечивать методы, которые физически не написаны.
➡️ Без плагина IDEA не увидит методов, и всё будет красным. 🟢 Пример: что генерирует @Builder
@Builder
public class Book {
    private String title;
    private int pages;
}
➡️ Под капотом Lombok добавляет
public static class BookBuilder {
    private String title;
    private int pages;

    public BookBuilder title(String title) {
        this.title = title;
        return this;
    }

    public BookBuilder pages(int pages) {
        this.pages = pages;
        return this;
    }

    public Book build() {
        return new Book(title, pages);
    }
}
➡️ И плюс метод Book.builder() — точка входа. 🟢 Хочешь увидеть это сам? Скомпилируй Lombok-класс и деобфусцируй .class:
javac Book.java
javap -p Book.class
➡️ Ты увидишь, что методы реально есть, просто их не было в твоём .java-файле. 🗣 Запомни: Lombok — это макросы на этапе компиляции, а не runtime-библиотека.