p.blog
Unternehmenskultur, Softwareentwicklung und Architektur

11. Juli 2022

Code entschlacken mit Lombok – Altbewährtes und ein Blick in die Zukunft

}

3 Minuten Lesedauer

Lombok dürfte vielen Entwicklern aus der Java-Welt inzwischen ein Begriff sein. Kein Wunder: Die Möglichkeit, verschiedene Standard-Codeschnipsel durch Annotationen kapseln zu können, fördert die Übersichtlichkeit des Codes enorm. Redundante Bestandteile fallen weg und man kann sich auf das Wesentliche konzentrieren. Wie das funktioniert, welche Features uns in Zukunft noch erwarten könnten und was mein Fazit zum Tool insgesamt ist, erfahrt ihr auf diesem kurzen Rundflug.

Photo by Diana Polekhina on Unsplash

 

Setup und erste Magie

Um Lombok in euer Projekt zu integrieren, fügt ihr einfach die Dependency im Build-Tool eurer Wahl hinzu. Als Beispiel Maven:

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.24</version>
        <scope>provided</scope>
    </dependency>
</dependencies>

Schon seid ihr einsatzbereit und könnt anfangen, euren Code aufzuräumen.

@Getter/@Setter

In Plain-Java würde man üblicherweise Folgendes sehen:

private final String property;

public void setProperty(String value)
  this.property = value;
}

public String getProperty() {
  return property;
}

 

Mit Lombok ersetzt man es einfach durch die beiden Zeilen:

@Getter
@Setter

private final String property;

 

Und fertig sind unsere Methoden. In diesem Fall gelten die Annotations spezifisch für dieses eine Attribut, sie können aber auch auf Klassenebene verwendet werden. Zwar schreiben hoffentlich die wenigsten Getter und Setter selbst, sondern lassen sie sich von der IDE generieren, kompakter ist der Code so aber allemal.

Konstruktoren

Werden auf Klassenebene hinzugefügt. Hier gibt es verschiedene Optionen, die Unterschiede kurz zusammengefasst:

@NoArgsConstructor erzeugt leeren Konstruktor kann mit (“force=true”) erzwungen werden, falls final-Felder enthalten sind, werden diese mit null initialisiert
@AllArgsConstructor erzeugt Konstruktor für alle Felder
@RequiredArgsConstructor erzeugt Konstruktor für alle final-Felder

Außerdem gilt, dass die Verwendung einer solchen Annotation nicht weitere, spezifischere Konstruktoren ausschließt. Ihr könnt also eigene und von Lombok generierte zusammen verwenden.

Darüber hinaus gibt es noch Basisfunktionen wie @EqualsAndHashCode oder @ToString – der Name ist Programm. Mit @NotNull an einem Methodenp-Parameter musst du dich nicht mehr mit NullPointerExceptions herumschlagen.

Spannende Features in der Testphase

So viel zu den Basics. Dabei bleibt es aber nicht, denn der Funktionsumfang von Lombok wird regelmäßig erweitert. Dabei erscheinen die potenziellen neuen Features erstmal in einem Experimental-Status. Bewähren sie sich in diesem Zeitraum, folgt eine Beförderung zu stable und die Erweiterung bleibt sicher bestehen. Nachfolgend möchte ich auf ein paar dieser Experimental-Features eingehen und euch zeigen, warum ihr sie schon mal im Hinterkopf haben solltet. Von manchen bin ich nämlich so überzeugt, dass ich fest mit einer Promotion rechne.

@SuperBuilder und @Jacksonized

Die @Builder-Annotation ist ja bereits ein festes Feature von Lombok und findet zum Beispiel im Umfeld von APIs großen Anklang. Statt einer mehrteiligen Instanziierung mit Verwendung der Setter-Methoden können Objekte mit einem einzigen Befehl “gebaut” und anschließend verwendet werden.

Diese Funktionalität wird mit @SuperBuilder um das Prinzip der Vererbung erweitert. Super-Aufrufe des übergeordneten Konstruktors gehören damit der Vergangenheit an. Sobald betroffene Klassen – die Vererbende und die Erbende(n) – mit der Annotation versehen wurden, lassen sich alle Attribute aus einem Builder-Aufruf heraus festlegen:

@SuperBuilder
public class Person {

  private final String firstName;
  private final String lastName;
}
@SuperBuilder
public class Employee extends Person {

  private final String employeeId;
}
Employee.builder().firstName("Donald")
                  .lastName("Trump")
                  .employeeId("1D1OT")
                  .build();

Ein Problem bestand zwischenzeitlich noch darin, dass die Jackson-Library nicht mit dieser Konstruktor-Alternative zurecht kam. Sie versteht ohne Wink mit dem Zaunspfahl nicht, dass zum Serialisieren/Deserialisieren der Builder verwendet werden soll. Zwar konnte man dem durch einige weitere Annotations entgegenwirken, aber Boilerplate-Code für ein Tool, das diesen eigentlich reduzieren soll? Klingt falsch. An dieser Stelle kommt @Jacksonized ins Spiel: Es vereint diese Anpassungen in einer Annotation und sorgt für einen reibungslosen Ablauf. Funktioniert natürlich auch für den normalen @Builder ohne Vererbung.

@SuperBuilder
@Jacksonized
public class Person { 
...

Gerade den @SuperBuilder und @Jacksonized im Zusammenspiel möchte ich nicht mehr missen. Das Ergebnis sind super saubere und übersichtliche Model-Klassen mit einer nahtlosen JSON-Integration.

Um diese Features nutzen zu können, benötigt ihr mindestens Lombok v1.18.14.

Fazit

Ich muss gestehen, ich bin ein großer Fan von Lombok. Die Vorteile liegen klar auf der Hand und gehen mitunter Baustellen an, die Java seit jeher zu keinem besonders guten Image verholfen haben. Alles schrumpft zusammen, selbst komplexere Klassen werden auf einen Blick fassbar.

Es gibt allerdings auch Gegenstimmen, die weniger Magie versteckt im Hintergrund haben wollen. Und das ist durchaus ein valider Punkt. Wo dir viel abgenommen wird, hast du zwangsläufig auch weniger Einblick darüber, was tatsächlich passiert. Gebündelte Annotations (wie @Data) können dazu führen, mehr generieren zu lassen als wirklich benötigt wird. Außerdem können zu viele Annotations auf einmal auch schnell unübersichtlich werden, was deren Einsatz dann etwas ad absurdum führt. Um dem vorzubeugen, sollte die Reihenfolge auf Klassenebene jeweils gleich sein.

Zusammenfassend bleibt wohl nur zu sagen: Es ist Geschmacksache und gesunder Menschenverstand schadet natürlich nie. Setzt Annotationen eher rar gesät ein, statt mit dem großen Eimer. Und nur dort, wo es auch wirklich Sinn ergibt und euch die Arbeit erleichtert.

Teile diesen Beitrag