Datenklassen in Kotlin

Datenklassen in Kotlin

1. Überblick

Die Kotlin-Sprache führt das Konzept der Datenklassen ein, die einfache Klassen darstellen, die als Datencontainer verwendet werden und keine zusätzliche Logik enthalten. Einfach ausgedrückt, die Kotlin-Lösung ermöglicht es uns, das Schreiben von viel Boilerplate-Code zu vermeiden.

In diesem kurzen Artikel werfen wir einen Blick auf Datenklassen in Kotlin und vergleichen sie mit ihren Java-Gegenstücken.

2. Kotlin Setup

Informationen zum Einrichten des Kotlin-Projekts finden Sie in unserem Tutorial zuintroduction to the Kotlin Language.

3. Datenklassen in Java

Wenn wir einenMovie-Eintrag in Java erstellen möchten, müssen wir viel Boilerplate-Code schreiben:

public class Movie {

    private String name;
    private String studio;
    private float rating;

    public Movie(String name, String studio, float rating) {
        this.name = name;
        this.studio = studio;
        this.rating = rating;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getStudio() {
        return studio;
    }

    public void setStudio(String studio) {
        this.studio = studio;
    }

    public float getRating() {
        return rating;
    }

    public void setRating(float rating) {
        this.rating = rating;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;

        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + Float.floatToIntBits(rating);
        result = prime * result + ((studio == null) ? 0 : studio.hashCode());

        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;

        if (obj == null)
            return false;

        if (getClass() != obj.getClass())
            return false;

        Movie other = (Movie) obj;

        if (name == null) {
            if (other.name != null)
                return false;

        } else if (!name.equals(other.name))
            return false;

        if (Float.floatToIntBits(rating) != Float.floatToIntBits(other.rating))
            return false;

        if (studio == null) {
            if (other.studio != null)
                return false;

        } else if (!studio.equals(other.studio))
            return false;

        return true;
    }

    @Override
    public String toString() {
        return "Movie [name=" + name + ", studio=" + studio + ", rating=" + rating + "]";
    }
}

86 Codezeilen. Das ist eine Menge, um nur drei Felder in einer einfachen Klasse zu speichern.

4. Kotlin-Datenklasse

Jetzt erstellen wirthe same Movie class, with the same functionalities, using Kotlin:

data class Movie(var name: String, var studio: String, var rating: Float)

Wie wir sehen können, ist das massiv einfacher und sauberer. Konstruktor-,toString(), equals(), hashCode(),- und zusätzlichecopy()- undcomponentN()-Funktionen werden automatisch generiert.

4.1. Verwendungszweck

Eine Datenklasse wird wie andere Klassen instanziiert:

val movie = Movie("Whiplash", "Sony Pictures", 8.5F)

Jetzt sind die Eigenschaften und Funktionen von verfügbar:

println(movie.name)   //Whiplash
println(movie.studio) //Sony Pictures
println(movie.rating) //8.5

movie.rating = 9F

println(movie.toString()) //Movie(name=Whiplash, studio=Sony Pictures, rating=9.0)

4.2. Kopierfunktion

Diecopy()-Funktion wird erstellt, falls ein Objekt kopiert werden muss, das einige seiner Eigenschaften ändert, den Rest jedoch unverändert lässt.

val betterRating = movie.copy(rating = 9.5F)
println(betterRating.toString()) // Movie(name=Whiplash, studio=Sony Pictures, rating=9.5)

Java bietet keine klare, native Möglichkeit zum Kopieren / Klonen von Objekten. Wir könnten die SchnittstelleClonable,SerializationUtils.clone() odercloning constructor verwenden.

4.3. Zerstörungserklärungen

Deklarationen zur Destrukturierung ermöglichen es uns, Objekteigenschaften als einzelne Werte zu behandeln. Für jede Eigenschaft in unserer Datenklasse wird eincomponentN() generiert:

movie.component1() // name
movie.component2() // studio
movie.component3() // rating

Wir können auch mehrere Variablen aus dem Objekt oder direkt aus einer Funktion erstellen. Beachten Sie unbedingt die Verwendung von Klammern:

val(name, studio, rating) = movie

fun getMovieInfo() = movie
val(namef, studiof, ratingf) = getMovieInfo()

4.4. Datenklassenanforderungen

Um eine Datenklasse zu erstellen, müssen wir folgende Anforderungen erfüllen:

  • Der primäre Konstruktor muss mindestens einen Parameter haben

  • Alle primären Konstruktorparameter müssen alsval odervar markiert werden

  • Datenklassen können nicht abstrakt, offen, versiegelt oder inner sein

  • (vor 1.1.) Datenklassen dürfen nur Schnittstellen implementieren

Seit 1.1 können Datenklassen andere Klassen erweitern.

Wenn die generierte Klasse einen parameterlosen Konstruktor haben muss, müssen Standardwerte für alle Eigenschaften angegeben werden:

data class Movie(var name: String = "", var studio: String = "", var rating: Float = 0F)

5. Fazit

Wir haben Datenklassen in Kotlin, ihre Verwendung und Anforderungen, die reduzierte Menge an geschriebenem Boilerplate-Code und Vergleiche mit demselben Code in Java gesehen.

Wenn Sie mehr über Kotlin erfahren möchten, lesen Sie Artikel wieKotlin Java Interoperability und die bereits erwähntenIntroduction to the Kotlin Language.

Die vollständige Implementierung dieser Beispiele finden Sie in unserenGitHub project.