Project lombok в первую очередь был нацелен на облегчение написания entity классов, которые хранят данные, но не обрабатывают их. Для классов содержащих код у project lombok тоже есть вспомогательные аннотации.
@Log public class FileReadingService { @Synchronized @SneakyThrows public long readFile() { log.info("Going to count line in non-existent file in a thread-safe way."); return new BufferedReader(new InputStreamReader(new FileInputStream("/nonexistent"))) .lines().count(); } }
public class FileReadingServiceTest { @Test(expected = IOException.class) public void testFileReader() { FileReadingService testedObject = new FileReadingService(); testedObject.readFile(); } }
Nov 03, 2015 3:24:00 PM ru.easyjava.java.FileReadingService readFile INFO: Going to count line in non-existent file in a thread-safe way.
@Log
@Log вставляет в класс логгер, избавляя разработчика от радостей его ручного создания в каждом классе.
private static final java.util.logging.Logger log = java.util.logging.Logger.getLogger(LogExample.class.getName());
Именем логгера по умолчанию будет имя класса, но его можно изменить, передав параметр: @Log(topic=«captain»)
Очевидно, что project lombok поддерживается не только java.util.logging, существует ещё 5 аннотаций:
- @CommonsLog для работы с Apache commons logging
- @Log4J и @Log4J2 для первого и второго log4j
- @Slf4J и @XSlf4j для sl44j
@SneakyThrows
На мой взгляд самый сомнительный функционал project lombok. Аннотация @SneakyThrows обманывает компилятор и позволяет писать код, выбрасывающий checked exceptions без явного перечисления этих самых checked exceptions в сигнатуре метода. Разумеется checked vs unchecked есть тема холиварная, поэтому я её опущу, но используйте этот функционал с осторожностью.
Основных применений @SneakyThrows два: реализация какого-либо интерфейса, который не допускает check exceptions, а обрабатывать их не хочется/нет смысла, или код, который не может вызывать исключение. В официальной документации приводится пример с new String(someByteArray, «UTF-8») и UnsupportedEncodingException, которое не может быть выброшено в этом случае, так как jvm гарантирует доступность кодировки UTF-8.
Надо отметить, что если вы скрыли какое-то checked исключение из сигнатуры метода, его уже не получится поймать использую конкретный тип исключения, так как компилятор скажет, что никто не объявляет, что это исключение выбрасывается.
@Synchronized
@Synchronized это как synchronized, только лучше. Ключевое слово synchronized на методе обещает нам следующее: метод никогда не может быть исполнен одновременно в разных потоках и когда метод завершится, все изменения в этом объекте станут доступны всем нитям. Мы знаем, что на самом деле создаётся внутренняя блокировка на самом объекте, к которому принадлежит метод ( this) и если мы хотим блокироваться на каком-то другом объекте, то мы должны вручную этот объект создать и вручную же на нём блокироваться. @Synchronized делает ручную работу за нас: создаёт объект $lock и код метода заворачивается в synchronized($lock) { }. Статические методы тоже поддерживаются, объект для них будет называться $LOCK. В случае, если объектов для синхронизации должно быть несколько, их можно создать вручную, а их имена передать в аннотацию @Synchronized, попытка передать туда имя несуществующего объекта приведёт к ошибке.