Lombok @SneakyThrows — храбро бросаем проверяемые исключения там, где их ещё никто не бросал

Цикл статей «Project Lombok».

Следующая статья — «Lombok @Synchronized — правильная синхронизация».
Предыдущая статья — «Lombok @Builder».

Аннотация @SneakyThrows может быть использована для бросания проверяемых исключений без их объявления в throws метода. Эту немного спорную возможность нужно использовать с осторожностью, конечно. Код, генерируемый Lombok, НЕ будет игнорировать, оборачивать, заменять и модифицировать другим способом бросаемое исключение. Он просто обманывает компилятор. В JVM (файл class) все исключения: проверяемые и непроверяемые — все они могут быть брошены независимо от оператора throws. Вот почему это работает.

Общие случаи, когда вы хотите уклониться от механизма проверяемых исключений, вращаются вокруг двух ситуаций:

  • Без нужды строгий интерфейс, Например, Runnable — какое бы исключение не бросалось из метода run: проверяемое или непроверяемое — оно будет передано в обработчик исключений Thread-а. Перехватывание проверяемых исключений и оборачивание их в какое-нибудь RuntimeException только прячет реальную причину проблемы.
  • Невозможное исключение. Например, new String(someByteArray, "UTF-8"); объявляет, что оно может бросить исключение UnsupportedEncodingException, но согласно спецификации JVM UTF-8 всегда доступен. Исключение UnsupportedEncodingException здесь как ClassNotFoundError при использовании объекта String, и вы не перехватываете никого из них.

Будьте осторожны, невозможно перехватить брошенные проверяемые исключения, которые не были объявлены в throws, так как javac не позволяет вам написать блок catch для исключения, которое ни один метод внутри блока try не объявил в операторе throws. Эта проблема не связана с теми двумя случаями, перечисленными выше, так что расценивайте это как предупреждение, что вы не должны использовать механизм @SneakyThrows бездумно.

Вы можете передать любое количество исключений в аннотацию @SneakyThrows. Если вы не передаёте никаких исключений, то вы можете генерировать (бросать) любое исключение.

ЗАМЕТКА: с Lombok версии ниже 0.10, в отличие от других трансформаций lombok, вам нужно положить lombok.jar в classpath при запуске программы.

С использованием Lombok

Чистая Java

Поддерживаемые ключи конфигурации

Lombok помечает любое использование @SneakyThrows предупреждением или ошибкой, если настроено.

Примечания

Поскольку @SneakyThrows — это часть реализации, а не часть сигнатуры метода, то попытка указать проверяемое исключение в @SneakyThrows, которое не генерируется ни одним методом, является ошибкой. (Для оператора throws вполне можно указывать исключения, которые не указаны ни в одном метода. Там это сделано для нормальной работы дочерних классов). Так же @SneakyThrows не наследуется.

Если вы укажете @SneakyThrows для конструктора, то любой вызов перегруженного конструктора или конструктора базового класса исключается из обработки @SneakyThrows. Это ограничение Java: вызов перегруженного конструктора или конструктора базового класса ДОЛЖЕН быть первой инструкцией в конструкторе. Их нельзя вкладывать в блок try/catch.

Аннотация @SneakyThrows для пустого метода или пустого конструктора или конструктора, имеющего только вызов перегруженного варианта конструктора / конструктора базового класса приводит к отсутствию блока try/catch block и предупреждению.

 

Цикл статей «Project Lombok».

Следующая статья — «Lombok @Synchronized — правильная синхронизация».
Предыдущая статья — «Lombok @Builder».

Lombok @SneakyThrows — храбро бросаем проверяемые исключения там, где их ещё никто не бросал: 3 комментария

  1. Привет,
    для честного сравнения пример кода «Чистая Java» не должен импортировать lombok.
    И уж точно не вызывать Lombok.sneakyThrow.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *