Allgemeine Java-Objektfunktionalität mit Project Lombok

Project Lombok ist eine kleine Bibliothek, mit der Sie die Menge an Java-Code reduzieren können, die üblicherweise für Java-Klassen geschrieben wird. Project Lombok erledigt dies über Anmerkungen, die der Java-Klasse hinzugefügt werden können, für die gängige Methoden gewünscht werden. Die meisten Anmerkungen sind in ihren Namen selbstbeschreibend: @Getter, @Setter, @EqualsAndHashCode, @ToString und @NoArgsConstructor sind Beispiele. In diesem Beitrag zeige ich, wie Sie einfache Lombok-Annotationen anwenden, um diese häufig geschriebenen Methoden einer Java-Klasse hinzuzufügen.

Hier ist eine einfache Klasse ohne vordefinierte überschriebene Version von toString ().

toString-less Person.java

package dustin.examples; /** * Simple Person class without boilerplate. * * @author Dustin */ public class Person { private String lastName; private String firstName; } 

Wenn die obige Klasse generiert und ihre implizit vererbte (von Object) toString () -Methode aufgerufen wird, sieht die Ausgabe wie im nächsten Bild gezeigt aus.

Wir könnten eine explizite toString () -Methode schreiben oder Project Lombok verwenden. Das nächste Code-Snippet demonstriert den Project Lombok-Ansatz.

Person.java mit Lomboks @ ToString-Anmerkung

package dustin.examples; import lombok.ToString; /** * Simple Person class without boilerplate. * * @author Dustin */ @ToString public class Person { private String lastName; private String firstName; } 

Die Ausgabe vom Drucken des Inhalts dieser Klasse mit einem von Lombok bereitgestellten toString () wird als Nächstes angezeigt.

Es gibt jetzt eine bessere toString () - Darstellung des Person-Objekts, aber seine Felder werden immer noch nicht initialisiert, sodass nur Nullwerte angezeigt werden. Wir können Lombok erneut verwenden, um den Konstruktor zu erstellen.

Person.java mit Lomboks @ AllArgsConstructor Annotation

package dustin.examples; import lombok.AllArgsConstructor; import lombok.ToString; /** * Simple Person class without boilerplate. * * @author Dustin */ @ToString @AllArgsConstructor public class Person { private String lastName; private String firstName; } 

Ich kann (muss) jetzt Parameter bei der Instanziierung des Person-Objekts übergeben. Die Ergebnisse werden im nächsten Bildschirmbild angezeigt. In diesem Fall zeigt mein Client-Code (Main.java) einen Kompilierungsfehler in NetBeans an, da NetBeans nicht glaubt, dass in Person ein Konstruktor vorhanden ist, der zwei Zeichenfolgen akzeptiert. Trotz der roten, schnörkellosen Markierungen wird der Code erstellt, wenn ich NetBeans auffordere, ihn zu erstellen.

Eine Klasse wie Person.java ist häufig eine Datenklasse, die für Vergleiche und möglicherweise für hashCode-basierte Erfassungsschlüssel verwendet werden muss. Es ist wichtig, die Implementierungen equals (Object) und hashCode () korrekt zu erstellen und sicherzustellen, dass sie zusammen erstellt werden. Da die übergeordnete Object-Klasse standardmäßige Methoden equals und hashCode bereitstellt, kann Java-Code mit Person-Instanzen equals und / oder hashCode ausführen, aber es ist unwahrscheinlich, dass sie wirklich das sind, was man wirklich will. Wenn die ausführbare Hauptklasse in die nächste Codeliste geändert wird, wird danach die Ausgabe angezeigt, aus der hervorgeht, dass der Gleichheitsvergleich vollständig auf der Grundlage der Identität und nicht auf der Grundlage des Inhalts durchgeführt wird.

Main.java That Tests entspricht () Implementierung

package dustin.examples; import static java.lang.System.out; /** * Simple Main for uses Project Lombok-powered classes. * * @author Dustin */ public class Main { public static void main(final String[] arguments) { //final Person person = new Person(); final Person person = new Person("Miles", "Linda"); out.println(person); final String sameLastName = "Smith"; final String sameFirstName = "Sam"; final Person person1 = new Person(sameLastName, sameFirstName); final Person person2 = new Person(sameLastName, sameFirstName); if (person1.equals(person2)) { out.println("Same person!"); } else { out.println("Different people!"); } } } 

Dies ist hier fast nie erwünscht. Stattdessen ist eine explizite gleichwertige Implementierung erforderlich. Ich mag die Tatsache, dass die Lombok-Annotation dafür, @EqualsAndHashCode, nur beide zusammen generiert, da es nicht sinnvoll ist, sie einzeln explizit zu überschreiben. Die Liste der Person.java-Klassen wird als Nächstes mit der Annotation @EqualsAndHashCode angezeigt.

Person.java mit @EqualsAndHashCode

package dustin.examples; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.ToString; /** * Simple Person class without boilerplate. * * @author Dustin */ @ToString @AllArgsConstructor @EqualsAndHashCode public class Person { private String lastName; private String firstName; } 

Die Ausgabe ist jetzt besser.

Ich habe immer noch keine gute Möglichkeit, bei Bedarf auf jedes öffentliche Feld einzeln zuzugreifen. Wenn ich zum Beispiel etwas in meinem Code basierend auf dem Nachnamen tun wollte, habe ich keine gute Möglichkeit, dies zu erreichen, ohne drastische Schritte zu unternehmen. Ich kann Lombok hier wieder benutzen.

In diesem Beispiel nehmen wir an, dass wir eine fehlerhafte Annahme getroffen haben, dass sich nur der Nachname der Person ändern könnte. Aufgrund dieser Annahme stellen wir nur eine Lombok @ Setter-Annotation für den Nachnamen bereit, jedoch eine @ Getter-Annotation für beide Felder. Der geänderte Personencode wird als nächstes angezeigt.

Person.java mit @Getter und @Setter

package dustin.examples; import lombok.AllArgsConstructor; import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.Setter; import lombok.ToString; /** * Simple Person class without boilerplate. * * @author Dustin */ @ToString @AllArgsConstructor @EqualsAndHashCode public class Person { @Getter @Setter private String lastName; @Getter private String firstName; } 

Hier ist die aktualisierte Hauptklasse, um dieses Beispiel auszuführen:

Main.java, das New Setter / Getter nutzt

package dustin.examples; import static java.lang.System.out; /** * Simple Main for uses Project Lombok-powered classes. * * @author Dustin */ public class Main { public static void main(final String[] arguments) { //final Person person = new Person(); final Person person = new Person("Miles", "Linda"); out.println(person); final String sameLastName = "Smith"; final String sameFirstName = "Sam"; final Person person1 = new Person(sameLastName, sameFirstName); final Person person2 = new Person(sameLastName, sameFirstName); if (person1.equals(person2)) { out.println("Same person!"); } else { out.println("Different people!"); } final Person accessiblePerson = new Person("Garzminski", "Gary"); out.println("The last name is " + accessiblePerson.getLastName()); out.println("The first name is " + accessiblePerson.getFirstName()); //accessiblePerson.setFirstName("Grady"); accessiblePerson.setLastName("Garfunkel"); out.println("The new last name is " + accessiblePerson.getLastName()); } } 

Ich musste den Aufruf auskommentieren, um den Vornamen der Person festzulegen, damit der Code erstellt wird. Es wird jetzt wie im nächsten Screenshot gezeigt ausgeführt.

Es ist wahrscheinlich, dass diese Sammlung von Lombok-Anmerkungen häufig erwünscht ist, insbesondere für datenorientierte Klassen. Aus diesem Grund bietet Project Lombok aggregierte Anmerkungen wie @Data, die eine Sammlung dieser Anmerkungen enthalten. In diesem Fall hätte ich mich den einzelnen Anmerkungen, die ich mithilfe von @Data bereitgestellt habe, sehr ähnlich verhalten können. Die Annotation @Data führt dazu, dass Lombok @Getter auf alle Felder und @Setter auf alle nicht endgültigen Felder anwendet. Der andere große Unterschied zu dem, was ich verwendet habe, ist, dass es @RequiredArgsConstructor anstelle von @AllArgsConstructor verwendet.

Eine der besten Möglichkeiten, um zu sehen, was Project Lombok mit der kompilierten .class-Datei gemacht hat, ist die Verwendung von Javap. Dies wird im nächsten Screenshot gezeigt.

Wir sehen in dieser Ausgabe, dass eine Reihe von Methoden, die üblicherweise als Boilerplate-Code verwendet werden, in der kompilierten Person.class verfügbar sind. Es gibt einen parametrisierten Konstruktor mit zwei Argumenten, hashCode (), equals (Object), toString () und die erwarteten get- und set-Methoden.

Das Projekt Lombok ist nicht ohne Bedenken und Einschränkungen. Viele davon sind in Antworten auf Hamlet D'Arcys Beitrag Java Without the Boilerplate - Project Lombok artikuliert. Eine Einschränkung ist die reduzierte Unterstützung in anderen IDEs als Eclipse (obwohl es eine anständige NetBeans-Unterstützung gibt und Javac unterstützt wird). Ein Problem ist die Notwendigkeit, dass andere Benutzer den Code verwenden und pflegen, um eine neue Abhängigkeit von Lombok zu haben. Dieses Problem kann durch die Verwendung des Delomboks, der bei Bedarf im Erstellungsprozess verwendet werden kann, etwas gemildert werden.

Weitere Artikel und Blog-Beiträge zu Project Lombok sind das Projekt Lombok - Nie wieder Java-Boilerplate-Code schreiben, Java ohne Boilerplate - Projekt Lombok, Projekt Lombok: Tschüss Boilerplate, Java Posse's Project Lombok-Interview, Projekt Lombok: Java-Ausführlichkeit ein Ende setzen , Project Lombok - Ein Muss in Ihrem Java Toolkit, Project Lombok: Interessante Verknüpfungen mit Annotation Processor, Interview: Reinier und Roel auf Lombok, Reduzierung des Boilerplate-Codes mit Project Lombok, Schnelle Entwicklung mit Lombok, Lombok Reduziert Ihren Boilerplate-Code und Bessere Alternative für Getter und Setter.

Diese Geschichte "Gemeinsame Java-Objektfunktionalität mit Project Lombok" wurde ursprünglich von JavaWorld veröffentlicht.