Цикл статей «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
1 2 3 4 5 6 7 8 9 10 11 12 13 |
import lombok.SneakyThrows; public class SneakyThrowsExample implements Runnable { @SneakyThrows(UnsupportedEncodingException.class) public String utf8ToString(byte[] bytes) { return new String(bytes, "UTF-8"); } @SneakyThrows public void run() { throw new Throwable(); } } |
Чистая Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
import lombok.Lombok; public class SneakyThrowsExample implements Runnable { public String utf8ToString(byte[] bytes) { try { return new String(bytes, "UTF-8"); } catch (UnsupportedEncodingException e) { throw Lombok.sneakyThrow(e); } } public void run() { try { throw new Throwable(); } catch (Throwable t) { throw Lombok.sneakyThrow(t); } } } |
Поддерживаемые ключи конфигурации
1 |
lombok.sneakyThrows.flagUsage = [warning | error] (default: not set) |
Lombok помечает любое использование @SneakyThrows предупреждением или ошибкой, если настроено.
Примечания
Поскольку @SneakyThrows — это часть реализации, а не часть сигнатуры метода, то попытка указать проверяемое исключение в @SneakyThrows, которое не генерируется ни одним методом, является ошибкой. (Для оператора throws вполне можно указывать исключения, которые не указаны ни в одном метода. Там это сделано для нормальной работы дочерних классов). Так же @SneakyThrows не наследуется.
Если вы укажете @SneakyThrows для конструктора, то любой вызов перегруженного конструктора или конструктора базового класса исключается из обработки @SneakyThrows. Это ограничение Java: вызов перегруженного конструктора или конструктора базового класса ДОЛЖЕН быть первой инструкцией в конструкторе. Их нельзя вкладывать в блок try/catch.
Аннотация @SneakyThrows для пустого метода или пустого конструктора или конструктора, имеющего только вызов перегруженного варианта конструктора / конструктора базового класса приводит к отсутствию блока try/catch block и предупреждению.
Цикл статей «Project Lombok».
Следующая статья — «Lombok @Synchronized — правильная синхронизация».
Предыдущая статья — «Lombok @Builder».
Привет,
для честного сравнения пример кода «Чистая Java» не должен импортировать lombok.
И уж точно не вызывать Lombok.sneakyThrow.
Я так и не понял для чего эта хрень нужна