Project Lombok: ordine e pulizia in Java
Uno degli strumenti che dovrebbe necessariamente far parte dell’“arsenale del giovane programmatore Java” è certamente Project Lombok.
Project Lombok è una simpatica libreria che permette di scrivere codice Java estremamente pulito e conciso riducendo drasticamente la verbosità del linguaggio.
Tramite l’utilizzo di Java annotation (e reflection) la libreria genererà per noi il codice di getter e setter, costruttori, metodi toString
e molti altri elementi utili (e noiosi da definire di volta in volta).
Installazione
Se stiamo usando Maven nel nostro progetto, possiamo aggiungere Project Lombok come dipendenza:
Se invece state utilizzando altri build automation tool, vi rimando alla sezione Install => Build tools del sito ufficiale.
Dichiarare classi
Uno dei motivi principali per utilizzare Project Lombok è la semplicità con cui riusciamo a dichiarare le nostre classi evitando di creare codice ripetitivo e difficile da manutenere.
La libreria mette a disposizione diverse annotazioni che ci consentono di definire quali elementi dovranno essere presenti nella nostra classe.
Par comprendere la semplificazione che si riesce ad ottenere, partiamo da un classico Java bean:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import java.util.Objects;
public class Point {
private int x;
private int y;
public Point() {
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Point point = (Point) o;
return x == point.x && y == point.y;
}
@Override
public int hashCode() {
return Objects.hash(x, y);
}
@Override
public String toString() {
return "Point{" + "x=" + x + ", y=" + y + '}';
}
}
Nonostante abbia scelto un oggetto molto semplice e non mi sia soffermato particolarmente sull’ implementazione del metodo hashCode
, ho ottenuto quasi 50 linee di codice!
Applichiamo ora le annotazioni di Project Lombok e facciamo un po’ di pulizia:
1
2
3
4
5
6
7
8
9
10
11
12
import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
@ToString
public class Point {
private int x;
private int y;
}
Che ve ne pare? 12 righe di codice… Niente male!
Ma possiamo fare di più:
1
2
3
4
5
6
7
8
9
import lombok.*;
@NoArgsConstructor
@AllArgsConstructor
@Data
public class Point {
private int x;
private int y;
}
Alcune utili annotazioni
Passiamo ora in rassegna le annotazioni utilizzate nell’esempio precedente:
-
@Getter
e@Setter
, prevedibilmente, sono le annotazioni che consentono di omettere gli accessors nella definizione della nostra classe. Entrambe le annotazioni possono essere utilizzate a livello di campo o a livello di classe: nel secondo caso, i metodiget
eset
verranno generati per tutti i campi non-statici. -
@EqualsAndHashCode
genera automaticamente i metodiequals
ehashCode
per la nostra classe. È possibile configurare quali campi verranno utilizzati per l’implementazione utilizzando gli elementiexclude
eof
dell’annotazione. -
@ToString
è ovviamente la scorciatoia da utilizzare per ottenere la rappresentazione testuale dei nostri oggetti. Anche in questo caso è possibile utilizzare gli elementiexclude
eof
dell’annotazione per configurare in modo granulare quali campi includere (o escludere). -
@NoArgsConstructor
consente di generare il costruttore senza argomenti, mentre@AllArgsConstructor
produce un costruttore sulla base di tutti i campi dichiarati nella classe.
Nell’ultimo esempio, infine, abbiamo utilizzato un’ulteriore scorciatoia: l’annotazione @Data
consente di applicare in un solo colpo @ToString
, @EqualsAndHashCode
, @Getter
, @Setter
e @RequiredArgsConstructor
. Quest’ultima annotazione non è però utile nel nostro caso, in quanto serve a generare un costruttore sulla base dei campi contrassegnati con l’annotazione @NonNull
.
Per la documentazione completa e per conoscere le altre annotazioni disponibili vi rimando alla pagina ufficiale del progetto.
var e val
Molto prima dell’arrivo di Java 10, in tempi non sospetti, Project Lombok metteva a disposizione degli sviluppatori Java la keyword var
.
Utilizzando var
possiamo sfruttare la type inference per le variabili locali, caratteristica a lungo invidiata a linguaggi più giovani.
In un certo senso, però, Project Lombok continua a fare meglio di Java, introducendo anche una seconda parola chiave, val
, attraverso la quale possiamo indicare una variabile final
:
Eseguendo il codice appena riportato potreste incappare in questo errore:
Error: Use of var is disabled by default. Please add 'lombok.var.flagUsage = ALLOW' to 'lombok.config' if you want to enable is.
Come chiaramente descritto, per utilizzare la keyword var
nel nostro codice sarà necessario aggiungere nella root del nostro progetto (di norma /src/main/java
) il file lombok.config
, abilitando esplicitamente la funzionalità.
Integrazione con gli IDE
Per lavorare con Project Lombok nel nostro IDE di fiducia tipicamente basta aggiungere un apposito plugin.
Per IntelliJ IDEA, il plugin da installare è Lombok Plugin. Piccola accortezza: per far sì che il plugin funzioni correttamente accertatevi che l’opzione Enable annotation processing, nel menù Settings => Build, Execution, Deployment => Compiler => Annotation Processors, sia spuntata.
Il plugin per Eclipse invece, è (insospettabilmente) incluso all’interno del jar contentente la libreria. Basterà scaricare il pacchetto dal sito di Project Lombok ed eseguirlo facendo doppio click.
Per gli altri ambienti di sviluppo attualmente supportati vi rimando alla sezione Install => IDEs della pagina ufficiale.
In conclusione
Chi è abituato a lavorare con Java sa bene quanto questo linguaggio possa essere verboso in alcune situazioni. Project Lombok ci risparmia un po’ di noia e ci aiuta a migliorare in modo sensibile la leggibilità del nostro codice.
Alla prossima,
David