История технологии сегодня — 17 апреля
ℹ️ Кто родился в этот день
Джованни Баттиста Риччоли (итал. Giovanni Battista Riccioli; 17 апреля 1598, Феррара — 25 июня 1671, Болонья) — итальянский астроном и теолог, автор труда «Новый Альмагест» (Almagestum Novum) — свода астрономических знаний своего времени. Вместе с Франческо Гримальди составил карту Луны и ввёл в практику обозначение лунных кратеров именами учёных.
🌐 Знаковые события
2014 – космический телескоп НАСА « Кеплер» подтвердил открытие первой планеты размером с Землю в обитаемой зоне другой звезды.
#Biography #Birth_Date #Events #17апреля
Джованни Баттиста Риччоли (итал. Giovanni Battista Riccioli; 17 апреля 1598, Феррара — 25 июня 1671, Болонья) — итальянский астроном и теолог, автор труда «Новый Альмагест» (Almagestum Novum) — свода астрономических знаний своего времени. Вместе с Франческо Гримальди составил карту Луны и ввёл в практику обозначение лунных кратеров именами учёных.
2014 – космический телескоп НАСА « Кеплер» подтвердил открытие первой планеты размером с Землю в обитаемой зоне другой звезды.
#Biography #Birth_Date #Events #17апреля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7
[Совет по Java #027]
Тема: double и float не подходят для циклов с условием на равенство.
Проблема: Числа с плавающей запятой (float, double) не могут быть точно представлены в двоичной системе.
Значение 0.1 в двоичном виде — это бесконечная периодическая дробь, поэтому в памяти хранится его приближение. При многократном прибавлении 0.1 к 0.0 накопленная погрешность приводит к тому, что переменная никогда не станет точно равной 1.0. В результате условие d != 1.0 остается истинным всегда, и цикл становится бесконечным.
Это классическая ошибка, особенно опасная в алгоритмах численного анализа, обработке сигналов и финансовых расчетах, где невнимательность к погрешности может привести к зависанию программы или некорректным результатам.
Решение: Никогда не используйте операторы равенства (==, !=) с числами с плавающей запятой в условиях циклов.
Вместо этого задавайте условие через сравнение с порогом (эпсилон) или используйте целочисленный счетчик, преобразуя его в плавающее значение на каждой итерации. Для известного количества итераций применяйте целочисленный цикл.
Для проверки близости используйте Math.abs(a - b) < epsilon.
Объяснение: Стандарт IEEE 754 определяет двоичное представление чисел с плавающей запятой. Десятичные дроби, не являющиеся суммой степеней двойки (например, 0.1 = 1/16 + 1/32 + 1/256 + ...), представляются бесконечным рядом, который обрезается до 53 бит мантиссы для double. Из-за этого ошибка округления накапливается.
В примере с циклом после десяти сложений получается не 1.0, а 0.9999999999999999. Условие d != 1.0 остается истинным, и цикл продолжается до бесконечности (точнее, до достижения бесконечности или переполнения).
Корректные подходы: использовать целочисленный счетчик (погрешность не накапливается, так как каждый раз вычисляется заново), применять сравнение с допустимой абсолютной погрешностью (epsilon), либо использовать BigDecimal для точных десятичных расчетов.
#Java #советы
Тема: double и float не подходят для циклов с условием на равенство.
Проблема: Числа с плавающей запятой (float, double) не могут быть точно представлены в двоичной системе.
Значение 0.1 в двоичном виде — это бесконечная периодическая дробь, поэтому в памяти хранится его приближение. При многократном прибавлении 0.1 к 0.0 накопленная погрешность приводит к тому, что переменная никогда не станет точно равной 1.0. В результате условие d != 1.0 остается истинным всегда, и цикл становится бесконечным.
Это классическая ошибка, особенно опасная в алгоритмах численного анализа, обработке сигналов и финансовых расчетах, где невнимательность к погрешности может привести к зависанию программы или некорректным результатам.
Решение: Никогда не используйте операторы равенства (==, !=) с числами с плавающей запятой в условиях циклов.
Вместо этого задавайте условие через сравнение с порогом (эпсилон) или используйте целочисленный счетчик, преобразуя его в плавающее значение на каждой итерации. Для известного количества итераций применяйте целочисленный цикл.
Для проверки близости используйте Math.abs(a - b) < epsilon.
public class FloatLoopProblem {
//Антипаттерн: бесконечный цикл
public static void badLoop() {
int iterations = 0;
for (double d = 0.0; d != 1.0; d += 0.1) {
iterations++;
System.out.printf("Итерация %d: %.20f%n", iterations, d);
if (iterations > 20) break; // защита от вечности
}
// Реальный вывод: d проходит через 0.0, 0.1, 0.2, ..., 0.9, 1.0000000000000002, ...
// Никогда не равно 1.0
}
//Ошибка с float
public static void badFloatLoop() {
for (float f = 0.0f; f != 1.0f; f += 0.1f) {
// Тоже бесконечный
}
}
//Решение 1: целочисленный счетчик
public static void goodLoopWithCounter() {
for (int i = 0; i <= 10; i++) {
double d = i * 0.1; // Вычисляем на каждой итерации
System.out.println("d = " + d);
}
}
//Решение 2: сравнение с эпсилон (допуском)
public static void goodLoopWithEpsilon() {
double d = 0.0;
final double EPSILON = 1e-10;
while (Math.abs(d - 1.0) > EPSILON) {
System.out.println("d = " + d);
d += 0.1;
}
System.out.println("Достигнуто: " + d);
}
//Решение 3: фиксированное количество итераций
public static void goodFixedIterations() {
int steps = 10;
for (int step = 0; step <= steps; step++) {
double ratio = (double) step / steps; // От 0.0 до 1.0
System.out.println(ratio);
}
}
// Демонстрация погрешности
public static void demonstratePrecision() {
double sum = 0.0;
for (int i = 0; i < 10; i++) {
sum += 0.1;
}
System.out.println("Сумма десяти 0.1: " + sum); // 0.9999999999999999
System.out.println("Сравнение с 1.0: " + (sum == 1.0)); // false
}
public static void main(String[] args) {
demonstratePrecision();
goodLoopWithCounter();
}
}Объяснение: Стандарт IEEE 754 определяет двоичное представление чисел с плавающей запятой. Десятичные дроби, не являющиеся суммой степеней двойки (например, 0.1 = 1/16 + 1/32 + 1/256 + ...), представляются бесконечным рядом, который обрезается до 53 бит мантиссы для double. Из-за этого ошибка округления накапливается.
В примере с циклом после десяти сложений получается не 1.0, а 0.9999999999999999. Условие d != 1.0 остается истинным, и цикл продолжается до бесконечности (точнее, до достижения бесконечности или переполнения).
Корректные подходы: использовать целочисленный счетчик (погрешность не накапливается, так как каждый раз вычисляется заново), применять сравнение с допустимой абсолютной погрешностью (epsilon), либо использовать BigDecimal для точных десятичных расчетов.
#Java #советы
👍3
Что выведет код?
#Tasks
public class Task170426 {
public static void main(String[] args) {
double sum = 0;
for (double d = 0.0; d != 1.0; d += 0.1) {
sum += d;
}
System.out.println(sum);
}
}#Tasks
👍2
👍2
Что такое JMX (Java Management Extensions)? 🤓
Ответ:
JMX — это технология для мониторинга и управления Java-приложениями.
Она позволяет в рантайме получать информацию о состоянии приложения (метрики, счетчики) и даже изменять параметры, не перезапуская приложение.
Основные понятия:
MBean (Managed Bean) — управляемый ресурс, который вы хотите мониторить;
MBean Server — реестр MBean'ов; адаптеры и коннекторы — для удаленного доступа (например, JConsole, VisualVM используют JMX).
#собеседование
Ответ:
Она позволяет в рантайме получать информацию о состоянии приложения (метрики, счетчики) и даже изменять параметры, не перезапуская приложение.
Основные понятия:
MBean (Managed Bean) — управляемый ресурс, который вы хотите мониторить;
MBean Server — реестр MBean'ов; адаптеры и коннекторы — для удаленного доступа (например, JConsole, VisualVM используют JMX).
#собеседование
Please open Telegram to view this post
VIEW IN TELEGRAM
👍4
История технологии сегодня — 18 апреля
ℹ️ Кто родился в этот день
Не нашел(
🌐 Знаковые события
1953 — в Англии совершил первый коммерческий полёт первый в мире турбовинтовой самолёт.
#Biography #Birth_Date #Events #18апреля
Не нашел(
1953 — в Англии совершил первый коммерческий полёт первый в мире турбовинтовой самолёт.
#Biography #Birth_Date #Events #18апреля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
С 11.04 по 17.04
Предыдущий пост(с 04.04 по 10.04)
Воскресный мотивационный пост:
Что случилось и почему сайт не работал или хронология одного хренового утра
Запись встреч/видео:
В процессе подготовки...
Обучающие статьи:
Раздел 9. Исключения, логирование, отладка
Глава 1. Иерархия исключений (Exceptions)
try-catch-finally – правильная обработка и освобождение ресурсов
try-with-resources (Java 7+) – автоматическое закрытие AutoCloseable
[Совет по Java #025]
Тема: ThreadLocal может вызвать утечку в серверах приложений.
[Совет по Java #026]
Тема: Синхронизация (synchronized) по строковой константе опасна.
[Совет по Java #027]
Тема: double и float не подходят для циклов с условием на равенство.
Полезные статьи и видео:
Где хранить код? Сравнение GitHub, GitLab и Bitbucket
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
Предыдущий пост(с 04.04 по 10.04)
Воскресный мотивационный пост:
Что случилось и почему сайт не работал или хронология одного хренового утра
Запись встреч/видео:
В процессе подготовки...
Обучающие статьи:
Раздел 9. Исключения, логирование, отладка
Глава 1. Иерархия исключений (Exceptions)
try-catch-finally – правильная обработка и освобождение ресурсов
try-with-resources (Java 7+) – автоматическое закрытие AutoCloseable
[Совет по Java #025]
Тема: ThreadLocal может вызвать утечку в серверах приложений.
[Совет по Java #026]
Тема: Синхронизация (synchronized) по строковой константе опасна.
[Совет по Java #027]
Тема: double и float не подходят для циклов с условием на равенство.
Полезные статьи и видео:
Где хранить код? Сравнение GitHub, GitLab и Bitbucket
Как и всегда, задачи можно найти под тегом - #Tasks, вопросы с собеседований - #собеседование
🔥3👍2
This media is not supported in your browser
VIEW IN TELEGRAM
Тестировщики они такие, да 😁
Please open Telegram to view this post
VIEW IN TELEGRAM
🤣3🤓1
История технологии сегодня — 19 апреля
ℹ️ Кто родился в этот день
Андре́й Петро́вич Ершо́в (19 апреля 1931, Рубежное, Рубежанский район, Старобельский округ, УССР, Советский Союз — 8 декабря 1988, Новосибирск, Новосибирская область, Советский Союз) — советский учёный, один из пионеров теоретического и системного программирования, создатель Сибирской школы информатики, академик АН СССР (1980). Его работы оказали влияние на формирование и развитие вычислительной техники не только в СССР, но и во всём мире.
Фредери́к Фи́ллипс Брукс-младший (англ. Frederick Phillips Brooks, Jr.; 19 апреля 1931, Дарем, Северная Каролина — 17 ноября 2022, Чапел-Хилл, Северная Каролина) — американский учёный в области теории вычислительных систем, автор книги «Мифический человеко-месяц». Управлял разработкой OS/360 в IBM. Награждён Премией Тьюринга в 1999 году.
🌐 Знаковые события
1965 — Гордоном Муром сформулирован так называемый «закон Мура», согласно которому количество транзисторов в кристалле микропроцессора удваивается каждые два года.
2021 — вертолёт НАСА Ingenuity стал первым летательным аппаратом землян, совершившим полёт на другой планете.
#Biography #Birth_Date #Events #19апреля
Андре́й Петро́вич Ершо́в (19 апреля 1931, Рубежное, Рубежанский район, Старобельский округ, УССР, Советский Союз — 8 декабря 1988, Новосибирск, Новосибирская область, Советский Союз) — советский учёный, один из пионеров теоретического и системного программирования, создатель Сибирской школы информатики, академик АН СССР (1980). Его работы оказали влияние на формирование и развитие вычислительной техники не только в СССР, но и во всём мире.
Фредери́к Фи́ллипс Брукс-младший (англ. Frederick Phillips Brooks, Jr.; 19 апреля 1931, Дарем, Северная Каролина — 17 ноября 2022, Чапел-Хилл, Северная Каролина) — американский учёный в области теории вычислительных систем, автор книги «Мифический человеко-месяц». Управлял разработкой OS/360 в IBM. Награждён Премией Тьюринга в 1999 году.
1965 — Гордоном Муром сформулирован так называемый «закон Мура», согласно которому количество транзисторов в кристалле микропроцессора удваивается каждые два года.
2021 — вертолёт НАСА Ingenuity стал первым летательным аппаратом землян, совершившим полёт на другой планете.
#Biography #Birth_Date #Events #19апреля
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥2👍1
11. Fallback и graceful degradation — когда всё сломалось, но пользователь этого не заметил
Retry, Circuit Breaker, Bulkhead, Timeout — мы настроили всё, но что получает пользователь, когда внешний сервис всё равно недоступен? В лучшем случае — 500 ошибку. В худшем — тишину. Это бизнес-потеря.
В этом видео мы закрываем последний пробел — Fallback (план «Б») и graceful degradation (грациозную деградацию).
Показываем, как система должна адаптироваться к отказам, а не падать вместе с зависимостями.
На примере OrderHub (Spring Boot + Resilience4j):
почему 500 ошибка — это не вариант, когда речь идёт о бизнесе;
как переработать существующие fallback-методы — от «бросить исключение» до «спасти заказ»;
локальная очередь на примере статуса PENDING;
шедулер для повторной обработки отложенных платежей;
Исходный код проекта на GitHub очень ждет Ваших звезд☺️ (Вам че блин, жалко?)
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!✌️
❗️ ❗️ ❗️ Огромная просьба - если Вам понравилась моя работа, распространите эту серию по всем доступным вам местам: телеграм, discord и прочим каналам. ❗️ ❗️ ❗️
Буду крайне благодарен🙂
Retry, Circuit Breaker, Bulkhead, Timeout — мы настроили всё, но что получает пользователь, когда внешний сервис всё равно недоступен? В лучшем случае — 500 ошибку. В худшем — тишину. Это бизнес-потеря.
В этом видео мы закрываем последний пробел — Fallback (план «Б») и graceful degradation (грациозную деградацию).
Показываем, как система должна адаптироваться к отказам, а не падать вместе с зависимостями.
На примере OrderHub (Spring Boot + Resilience4j):
почему 500 ошибка — это не вариант, когда речь идёт о бизнесе;
как переработать существующие fallback-методы — от «бросить исключение» до «спасти заказ»;
локальная очередь на примере статуса PENDING;
шедулер для повторной обработки отложенных платежей;
Исходный код проекта на GitHub очень ждет Ваших звезд
Ссылка на Youtube
Ссылка на Рутьюб
Смотрите, ставьте лайки, подписывайтесь на каналы!
Буду крайне благодарен
Please open Telegram to view this post
VIEW IN TELEGRAM
👍7🔥3
Java for Beginner
11. Fallback и graceful degradation — когда всё сломалось, но пользователь этого не заметил Retry, Circuit Breaker, Bulkhead, Timeout — мы настроили всё, но что получает пользователь, когда внешний сервис всё равно недоступен? В лучшем случае — 500 ошибку.…
Кто посмотрел?🧑💻
Дайте обратную связь? Что хорошо, какие моменты плохо?
Может что-то поменять?🤓
Заранее спасибо🕊
Дайте обратную связь? Что хорошо, какие моменты плохо?
Может что-то поменять?
Заранее спасибо
Please open Telegram to view this post
VIEW IN TELEGRAM
🔥3
История технологии сегодня — 20 апреля
ℹ️ Кто родился в этот день
Юрий Павлович Семёнов (род. 20 апреля 1935 года, Торопец, Калининская область) — советский и российский конструктор космической техники, педагог, профессор. Генеральный конструктор НПО «Энергия» (1989—2005).
Карл Алекса́ндр Мю́ллер (нем. Karl Alexander Müller; 20 апреля 1927, Базель — 9 января 2023, Цюрих) — швейцарский физик, лауреат Нобелевской премии по физике в 1987 году, совместно с Георгом Беднорцем, «за важный прорыв в физике, выразившийся в открытии сверхпроводимости в керамических материалах».
🌐 Знаковые события
1902 — супруги Мария и Пьер Кюри получили чистый радий.
1940 — В США продемонстрирован первый электронный микроскоп.
1972 — прилуняется пилотируемый космический корабль «Аполлон-16».
1998 — Фирма Intel анонсировала процессор Pentium II Xeon.
#Biography #Birth_Date #Events #20апреля
Юрий Павлович Семёнов (род. 20 апреля 1935 года, Торопец, Калининская область) — советский и российский конструктор космической техники, педагог, профессор. Генеральный конструктор НПО «Энергия» (1989—2005).
Карл Алекса́ндр Мю́ллер (нем. Karl Alexander Müller; 20 апреля 1927, Базель — 9 января 2023, Цюрих) — швейцарский физик, лауреат Нобелевской премии по физике в 1987 году, совместно с Георгом Беднорцем, «за важный прорыв в физике, выразившийся в открытии сверхпроводимости в керамических материалах».
1902 — супруги Мария и Пьер Кюри получили чистый радий.
1940 — В США продемонстрирован первый электронный микроскоп.
1972 — прилуняется пилотируемый космический корабль «Аполлон-16».
1998 — Фирма Intel анонсировала процессор Pentium II Xeon.
#Biography #Birth_Date #Events #20апреля
Please open Telegram to view this post
VIEW IN TELEGRAM
👍3
Раздел 9. Исключения, логирование, отладка
Глава 1. Иерархия исключений (Exceptions)
throws в сигнатуре метода – проброс исключений наверх. Когда это оправдано
Ключевое слово throws в сигнатуре метода Java формирует явный контракт между реализацией и вызывающим кодом. Оно объявляет, что метод может завершиться не нормально, выбросив одно из перечисленных checked-исключений, и перекладывает обязанность обработки на вызывающую сторону. Это часть системы проверяемых исключений Java, где компилятор гарантирует, что каждый potential failure path либо обработан локально, либо явно проброшен дальше по стеку вызовов.
Сигнатура с throws создает сильную связанность (tight coupling) между уровнями абстракции. Когда метод объявляет throws IOException, он экспонирует деталь реализации — использование ввода-вывода — в публичный API. Это называется утечкой абстракции (abstraction leak), когда низкоуровневые детали просачиваются через интерфейсы высокоуровневых компонентов. Вызов такого метода вынуждает все вызывающие методы также объявлять IOException в своих сигнатурах, создавая каскадную зависимость, которая распространяется от инфраструктурного слоя до пользовательского интерфейса.
Когда проброс оправдан: сценарии восстановления
Объявление исключений в сигнатуре методologically оправдано только в ограниченном наборе сценариев.
Первичный критерий — возможность и вероятность восстановления от ошибки на уровне вызывающего кода. Если исключение представляет собой ожидаемое, восстановимое условие, и вызывающий код может принять осмысленное альтернативное действие, тогда throws уместен.
Пример восстановимого сценария — бизнес-исключение InsufficientFundsException в платежной системе. Вызывающий код (координатор транзакции) может перехватить это исключение и предпринять альтернативные действия: предложить пользователю другой способ оплаты, разбить платеж на части, или отложить операцию. В этом случае checked-исключение с throws в сигнатуре метода processPayment форсирует явную обработку критичного бизнес-сценария.
Другой допустимый случай — низкоуровневые API, где пользователь должен осознанно принять решение об обработке ресурсов. Например, конструктор FileInputStream объявляет throws FileNotFoundException, потому что отсутствие файла — это условие, которое вызывающий код может предвидеть и обработать (создать файл, запросить альтернативный путь, продолжить без файла).
Однако современная практика свидетельствует о том, что даже в этих сценариях часто предпочтительны unchecked-исключения с документированием через @throws в Javadoc, а не checked-исключения с throws в сигнатуре.
Exception Translation: оборачивание vs проброс
В многослойной архитектуре прямой проброс низкоуровневых исключений наверх считается антипаттерном. Вместо этого применяется паттерн Exception Translation — перехват низкоуровневого исключения и оборачивание его в высокоуровневое, соответствующее абстракции текущего слоя.
Рассмотрим типичный сценарий с доступом к данным:
В этом примере DataAccessException — unchecked-исключение из Spring Framework, которое скрывает детали SQL, но сохраняет оригинальную причину (cause) для отладки. Это достигает нескольких целей: инкапсуляция деталей реализации, предоставление контекстно-зависимого сообщения об ошибке, и поддержание чистоты сигнатур методов бизнес-логики.
#Java #для_новичков #beginner #exception #throws
Глава 1. Иерархия исключений (Exceptions)
throws в сигнатуре метода – проброс исключений наверх. Когда это оправдано
Ключевое слово throws в сигнатуре метода Java формирует явный контракт между реализацией и вызывающим кодом. Оно объявляет, что метод может завершиться не нормально, выбросив одно из перечисленных checked-исключений, и перекладывает обязанность обработки на вызывающую сторону. Это часть системы проверяемых исключений Java, где компилятор гарантирует, что каждый potential failure path либо обработан локально, либо явно проброшен дальше по стеку вызовов.
Сигнатура с throws создает сильную связанность (tight coupling) между уровнями абстракции. Когда метод объявляет throws IOException, он экспонирует деталь реализации — использование ввода-вывода — в публичный API. Это называется утечкой абстракции (abstraction leak), когда низкоуровневые детали просачиваются через интерфейсы высокоуровневых компонентов. Вызов такого метода вынуждает все вызывающие методы также объявлять IOException в своих сигнатурах, создавая каскадную зависимость, которая распространяется от инфраструктурного слоя до пользовательского интерфейса.
Когда проброс оправдан: сценарии восстановления
Объявление исключений в сигнатуре методologically оправдано только в ограниченном наборе сценариев.
Первичный критерий — возможность и вероятность восстановления от ошибки на уровне вызывающего кода. Если исключение представляет собой ожидаемое, восстановимое условие, и вызывающий код может принять осмысленное альтернативное действие, тогда throws уместен.
Пример восстановимого сценария — бизнес-исключение InsufficientFundsException в платежной системе. Вызывающий код (координатор транзакции) может перехватить это исключение и предпринять альтернативные действия: предложить пользователю другой способ оплаты, разбить платеж на части, или отложить операцию. В этом случае checked-исключение с throws в сигнатуре метода processPayment форсирует явную обработку критичного бизнес-сценария.
Другой допустимый случай — низкоуровневые API, где пользователь должен осознанно принять решение об обработке ресурсов. Например, конструктор FileInputStream объявляет throws FileNotFoundException, потому что отсутствие файла — это условие, которое вызывающий код может предвидеть и обработать (создать файл, запросить альтернативный путь, продолжить без файла).
Однако современная практика свидетельствует о том, что даже в этих сценариях часто предпочтительны unchecked-исключения с документированием через @throws в Javadoc, а не checked-исключения с throws в сигнатуре.
Exception Translation: оборачивание vs проброс
В многослойной архитектуре прямой проброс низкоуровневых исключений наверх считается антипаттерном. Вместо этого применяется паттерн Exception Translation — перехват низкоуровневого исключения и оборачивание его в высокоуровневое, соответствующее абстракции текущего слоя.
Рассмотрим типичный сценарий с доступом к данным:
// Антипаттерн: прямая передача SQLException через все слои
public User findUser(String id) throws SQLException { // Нарушение абстракции
return database.query("SELECT * FROM users WHERE id = ?", id);
}
// Паттерн Exception Translation: оборачивание в доменное исключение
public User findUser(String id) {
try {
return database.query("SELECT * FROM users WHERE id = ?", id);
} catch (SQLException e) {
throw new DataAccessException("Failed to load user: " + id, e);
}
}
В этом примере DataAccessException — unchecked-исключение из Spring Framework, которое скрывает детали SQL, но сохраняет оригинальную причину (cause) для отладки. Это достигает нескольких целей: инкапсуляция деталей реализации, предоставление контекстно-зависимого сообщения об ошибке, и поддержание чистоты сигнатур методов бизнес-логики.
#Java #для_новичков #beginner #exception #throws
👍4
Важное различие между rethrow (повторным выбросом) и wrap (оборачиванием):
Rethrow — повторный выброс того же исключения без изменения типа, обычно после выполнения некоторых действий (логирование, откат транзакции):
Wrap — оборачивание исключения в новый тип, более подходящий для абстракции, с сохранением оригинальной причины:
При wrap критически важно передавать оригинальное исключение в конструктор нового исключения как cause. Это сохраняет полный стектрейс и позволяет при отладке проследить цепочку ошибок от высокоуровневого бизнес-сбоя до низкоуровневой технической причины.
Проблема интерфейсов и полиморфизма
Checked-исключения создают особые сложности при проектировании интерфейсов. Метод интерфейса, объявляющий throws CheckedException, обязывает все реализации работать с этим типом ошибки, даже если конкретная реализация не способна выбросить такое исключение.
Это нарушает принцип подстановки Лисков и создает искусственные ограничения для реализаций. Современный подход — использование unchecked-исключений в интерфейсах с документированием возможных сбоев через Javadoc, что позволяет реализациям самостоятельно решать, какие исключения выбрасывать, не нарушая контракт интерфейса.
Несовместимость с функциональным стилем
Java 8 ввела лямбда-выражения и Stream API, которые несовместимы с checked-исключениями. Функциональные интерфейсы (Function<T,R>, Consumer<T>, Supplier<T>) не объявляют checked-исключений в своих абстрактных методах, что делает невозможным прямое использование методов с throws в лямбдах.
Это архитектурное ограничение Java 8 фактически сигнализировало о том, что checked-исключения являются устаревшей концепцией для современного Java. Разработчики вынуждены прибегать к оборачиванию checked-исключений в RuntimeException внутри лямбд, что разрушает систему типов и делает checked-исключения бесполезными.
#Java #для_новичков #beginner #exception #throws
Rethrow — повторный выброс того же исключения без изменения типа, обычно после выполнения некоторых действий (логирование, откат транзакции):
public void processOrder(Order order) throws OrderValidationException {
try {
validate(order);
} catch (OrderValidationException e) {
auditLog.recordValidationFailure(order.getId(), e);
throw e; // Тот же тип, тот же стектрейс
}
}Wrap — оборачивание исключения в новый тип, более подходящий для абстракции, с сохранением оригинальной причины:
public Configuration loadConfiguration() {
try {
return parser.parse(configFile);
} catch (IOException e) {
throw new ConfigurationLoadException("Cannot read config from " + configFile, e);
}
}При wrap критически важно передавать оригинальное исключение в конструктор нового исключения как cause. Это сохраняет полный стектрейс и позволяет при отладке проследить цепочку ошибок от высокоуровневого бизнес-сбоя до низкоуровневой технической причины.
Проблема интерфейсов и полиморфизма
Checked-исключения создают особые сложности при проектировании интерфейсов. Метод интерфейса, объявляющий throws CheckedException, обязывает все реализации работать с этим типом ошибки, даже если конкретная реализация не способна выбросить такое исключение.
// Интерфейс объявляет checked-исключение
interface DataStore {
String read(String key) throws IOException;
}
// Реализация на основе памяти не может выбросить IOException,
// но вынуждена объявлять его или оборачивать в RuntimeException
class InMemoryStore implements DataStore {
@Override
public String read(String key) throws IOException { // Нелогично
return memoryMap.get(key);
}
}
Это нарушает принцип подстановки Лисков и создает искусственные ограничения для реализаций. Современный подход — использование unchecked-исключений в интерфейсах с документированием возможных сбоев через Javadoc, что позволяет реализациям самостоятельно решать, какие исключения выбрасывать, не нарушая контракт интерфейса.
Несовместимость с функциональным стилем
Java 8 ввела лямбда-выражения и Stream API, которые несовместимы с checked-исключениями. Функциональные интерфейсы (Function<T,R>, Consumer<T>, Supplier<T>) не объявляют checked-исключений в своих абстрактных методах, что делает невозможным прямое использование методов с throws в лямбдах.
// Метод с checked-исключением не может быть использован как лямбда
public String fetchUrl(String url) throws IOException {
return httpClient.get(url);
}
// Ошибка компиляции: IOException не обработано
List<String> results = urls.stream()
.map(this::fetchUrl) // Не компилируется
.collect(Collectors.toList());
Это архитектурное ограничение Java 8 фактически сигнализировало о том, что checked-исключения являются устаревшей концепцией для современного Java. Разработчики вынуждены прибегать к оборачиванию checked-исключений в RuntimeException внутри лямбд, что разрушает систему типов и делает checked-исключения бесполезными.
#Java #для_новичков #beginner #exception #throws
👍3