Zdradzę Ci sekret.
Lomboka używam w każdym projekcie z Javą z jaką mam styczność.
W każdym!
Zakładam, że Ty pewnie też.
Adnotacje @Data
, @Value
czy @RequiredArgsConstructor
zaoszczędzają mi mnóstwo czasu.
(Java == Boilerplate code, itd ;).
Ale!
To nie wszystko funkcje, jakie skrywa w sobie Lombok.
Zobacz 3 ciekawe możliwości, o których być może nie miałeś do tej pory pojęcia!
1. Sneaky Throws
Genialna sprawa.
Adnotacja, dzięki której nie muszę deklarować tam i z powrotem CheckedExceptions
, których i tak nie chcę w żaden sposób obsługiwać.
Albo gdy muszę zaimplementować interfejs, który nie deklaruje rzucania wyjątkami.
W takich sytuacjach sprawdza się znakomicie.
Przed korzystaniem z tej adnotacji kod może wyglądać tak.
class CustomerService {
private ObjectMapper mapper;
public Customer parseJson(String json) throws JsonParsingException {
return mapper.readValue(json, Customer.class);
}
}
Natomiast po dodaniu @SneakyThrows
nie ma potrzeby pisać smutnego throws Json....Exception
.
class CustomerService {
private ObjectMapper mapper;
@SneakyThrows
public Customer parseJson(String json) {
return mapper.readValue(json, Customer.class);
}
}
Genialne! 🙂
2. Cleanup
Umówmy się.
Java powstała już jakiś czasu.
I nie każda konstrukcja języka jest przyjemna do czytania.
Jak na przykład zamykanie zasobów implementujących interfejs AutoClosable
.
Przed Javą 7 wyglądało to tak:
public Customer parseFromFile(String file) {
Customer customer = null;
InputStream stream = new FileInputStream("foo.txt")
try {
customer = mapper.readValue(stream, Customer.class);
} finally {
stream.close();
}
return customer;
}
Od Javy 7 kwestia trochę się poprawiła.
Można wkładać zasób do bloku try-catch.
Zamknięty zostanie automatycznie.
public Customer parseFromFile(String file) {
Customer customer = null;
try (InputStream stream = new FileInputStream("foo.txt")) {
customer = mapper.readValue(stream, Customer.class);
}
return customer;
}
Ale czy można lepiej?
Oczywiście!
Z pomocą przychodzi Cleanup
z Lomboka 🙂
@SneakyThrows
public Customer parseFromFile(String file) {
@Cleanup InputStream stream = new FileInputStream(file);
return mapper.readValue(stream, Customer.class);
}
Zamiast 5 linii mamy 2! 🙂
3. Lazy Getter
Jak zaimplementować mechanizm leniwego inicjalizowania zmiennej?
Musimy podciągnąć rękawy, ubrudzić ręce i napisać taki smutny kodzik 👇
(Wzorzec podwójnego mechanizmu blokującego – double locking mechanism).
class Rates {
private Map<String, BigDecimal> rates = new HashMap<>();
private static final Object FETCH_LOCK = new Object();
public Map<String, BigDecimal> getRates() {
if(rates == null) {
synchronized(FETCH_LOCK) {
if(rates == null) {
rates = fetchRates();
}
}
}
return rates;
}
private Map<String, BigDecimal> fetchRates() {
// make a long HTTP call
}
}
17 linii i całkiem spore pole do popełnienia błędu..
A jak to wygląda z Lombokiem?
Dodajmy adnotację @Getter(lazy = true)
.
class Rates {
@Getter(lazy = true)
private final Map<String, BigDecimal> rates = fetchRates();
private Map<String, BigDecimal> fetchRates() {
// make a long HTTP call
}
}
6 lini!
I ten sam efekt.
Skoro nie widać różnicy, to po co przepłacać? 🙂
…no chyba, że masz płacone za liczbę linii kodu…
Ale to już temat na inną rozmowę 😅
Szybkie podsumowanie.
- Lombok jest zajebisty.
- Adnotacje @Value, @Data czy @RequiredArgsConstructor zna większość programistów.
- Ale stosowanie innych konstrukcji jak:
@SneakyThrows
,@Cleanup
czy@Getter(lazy = true)
może wznieść Twój kodzik na jeszcze wyższy poziom.
A Ty? Znałeś te adnotacje? 🙂
Znałeś 😁
💪🔥
Mnie ostatnio zadziwiła adnotacja @Builder z opcją toBuilder=true. Pozwala nie tylko na zrobienie obiektu z buildera, ale także buildera zainicjalizowanego wartościami obiektu. Wystarczy na obiekcie wywołać wygenerowana metodę toBuilder()
O sam o niej nie widziałem, fajna 🙂
Najlepszy feature lomboka to możliwość usunięcia go z projektu 😉
😃😃😃
Dzięki za ciekawy wpis przyda się z pewnością.
Dzięki Mateusz 🙂