Найти в Дзене
✔️ Java-совет, который спасает от тихих утечек ресурсов
Если работаете с BufferedReader, InputStream, OutputStream, FileReader, соединениями или другими ресурсами, которые нужно закрывать, используйте try-with-resources. Плохо: BufferedReader reader = new BufferedReader(new FileReader("data.txt")); String line; while ((line = reader.readLine()) != null) { System.out.println(line); } reader.close(); На первый взгляд всё нормально. Но если внутри чтения файла вылетит исключение, reader.close() может не выполниться. В итоге останутся открытые file handles, stream’ы или соединения...
1 час назад
Опубликовано фото
1 день назад
Java: никогда не доверяйте внешнему вводу напрямую
Пользовательский ввод нельзя сразу подставлять в SQL, путь к файлу или бизнес-логику. Плохой вариант: String sql = "SELECT * FROM users WHERE email = '" + email + "'"; Files.readString(Path.of("/data/" + filename)); int age = Integer.parseInt(request.getParameter("age")); На вид обычный код, но в нём сразу несколько проблем: • SQL-инъекции; • path traversal через ../; • некорректные типы и диапазоны; • мусорные данные, которые ломают логику дальше по системе. Правильный подход - валидировать данные на границе приложения и использовать безопасные API...
2 дня назад
Java и инкапсуляция без магии
Публичные поля выглядят удобно ровно до первого бага. account.balance = new BigDecimal("-100"); Код скомпилировался, объект изменился, бизнес-правило сломалось. Никакой проверки, никакого контроля, никакой гарантии, что BankAccount остаётся в корректном состоянии. Поэтому поле баланса не должно быть частью публичного API. Наружу можно отдать чтение, а изменение проводить через методы, где явно описаны правила: private BigDecimal balance = BigDecimal.ZERO; public BigDecimal getBalance() { return balance; } public void withdraw(BigDecimal amount) { if (amount...
3 дня назад
⚡️ Бинарный поиск, который вы выучили, скорее всего, был неправильным
Джон Бентли опубликовал реализацию бинарного поиска в *Programming Pearls* после того, как доказал её корректность и протестировал. Баг прожил почти 20 лет. Позже Джошуа Блох нашёл точно такую же ошибку в реализации бинарного поиска, которую сам написал для JDK. Исследование 1988 года показало: корректный бинарный поиск был только в 5 из 20 учебников. Ошибка проявляется только на массивах размером 2^30 элементов и больше. Проблема возникает...
1 неделю назад
🖥 Java постепенно закручивает гайки вокруг мутации final-полей через reflection
В JDK 26 появятся предупреждения, если код меняет final-поля через Reflection API. Это часть движения к тому, чтобы final снова означал реальную неизменяемость, а не «почти immutable, пока кто-то не сделал setAccessible(true)». Проблема старая: фреймворки, сериализация, DI и cloning часто создавали «пустой» объект, а потом дописывали поля напрямую. Для final это ломает саму идею конструктора, инвариантов и безопасной инициализации. Что предлагает Java-команда вместо этого: - использовать constructor...
1 неделю назад
Java-совет, который кажется мелочью, пока кто-то не сломает вам состояние объекта
Не возвращайте наружу изменяемые внутренние коллекции. Плохой вариант: ```java public List<String> getMembers() { return members; } Так вызывающий код получает прямой доступ к вашему внутреннему списку. После этого он может сделать: team.getMembers().clear(); И внезапно вся команда исчезла. Не через метод доменной модели, не через проверку прав, не через бизнес-логику, а просто потому что геттер отдал наружу ссылку на mutable state. Нормальный вариант: public List<String> getMembers() { return Collections...
1 неделю назад
💡 Java: вложенные if-else быстро превращают код в лабиринт
Когда вся логика уходит в глубокую вложенность, читать метод становится больно: основной сценарий спрятан где-то внизу, а перед ним несколько уровней проверок. Проще использовать guard clauses - ранние проверки с выходом из метода. Было: - проверяем user - внутри проверяем active - внутри проверяем order - внутри проверяем paid - только потом выполняем основное действие Стало:...
1 неделю назад
📌 Magic numbers в Java - мелкая привычка, которая потом превращает поддержку кода в археологию
Когда в коде встречается 86400, 7, 1.21 или 5000, компилятору всё равно. Человеку - нет. Через месяц уже приходится вспоминать, что это было: секунд в дне, дней сессии, НДС или задержка перед повторной попыткой. Плохой вариант выглядит так: if (sessionAgeSeconds > 86400 * 7) Формально код работает. Но смысл спрятан внутри чисел. Нормальный вариант: SECONDS_PER_DAY SESSION_DAYS VAT_RATE RETRY_DELAY_MS Теперь намерение видно прямо в месте вызова. Не нужно угадывать, почему именно 7, что означает 5000 и можно ли безопасно поменять значение...
2 недели назад
🖥 Java наконец начал подстраховывать разработчика там, где раньше легко прятались баги
В switch expression начиная с Java 14+ компилятор проверяет, что обработаны все возможные значения. Если у вас enum и вы забыли один из вариантов, код просто не соберётся. Это даёт сразу несколько плюсов: - меньше скрытых багов после рефакторинга - безопаснее расширять enum - компилятор...
2 недели назад
Spring Boot: когда нужно контролировать HTTP-ответ полностью
Если обычного return user уже мало, в Spring Boot есть ResponseEntity<T>. Он позволяет явно управлять всем ответом: • статусом HTTP • заголовками • телом ответа • обработкой ошибок • поведением API в нестандартных сценариях Пример: пользователь найден - возвращаем 200 OK, тело ответа и кастомный header. Пользователь не найден - возвращаем 404 NOT FOUND без лишней магии...
2 недели назад
Java-ошибка, которую лучше ловить на компиляции, а не в проде
В Java @Override - это не украшение над методом, а простая защита от глупых ошибок. Представь базовый класс: class Report { void print() { // ... } } Ты хочешь переопределить метод, но случайно пишешь prnt() вместо print(): class PDFReport extends Report { void prnt() { // ... } } Код скомпилируется. Но метод print() не переопределён. Ты просто создал новый метод с опечаткой, а старое поведение осталось на месте...
3 недели назад