Introduktion til uforanderlige

1. Introduktion

I denne artikel viser vi, hvordan man arbejder med biblioteket Immutables.

Biblioteket består af annoteringer og annoteringsprocessorer til generering og arbejde med serierbare og tilpassbare uforanderlige objekter.

2. Maven-afhængigheder

For at kunne bruge Immutables i dit projekt skal du tilføje følgende afhængighed af afhængigheder sektion af din pom.xml fil:

 org.immutables værdi 2.2.10 angivet 

Da denne artefakt ikke er påkrævet under kørsel, er det tilrådeligt at specificere stillet til rådighed rækkevidde.

Den nyeste version af biblioteket kan findes her.

3. Uforanderlige

Biblioteket genererer uforanderlige objekter fra abstrakte typer: Interface, Klasse, Kommentar.

Nøglen til at opnå dette er korrekt brug af @ Value.Immutable kommentar. Det genererer en uforanderlig version af en kommenteret type og præfikser sit navn med Uforanderlig nøgleord.

Hvis vi forsøger at generere en uforanderlig version af klassen ved navn “x“, Det genererer en klasse med navnet “ImmutableX”. Genererede klasser er ikke rekursivt uforanderlige, så det er godt at huske det.

Og en hurtig note - fordi Immutables bruger annoteringsbehandling, skal du huske at aktivere annoteringsbehandling i din IDE.

3.1. Ved brug af @ Value.Immutable Med Abstrakte klasser og Grænseflader

Lad os oprette en simpel abstrakt klasse Person bestående af to abstrakt accessor-metoder, der repræsenterer de felter, der skal genereres, og derefter kommentere klassen med @ Value.Immutable kommentar:

@ Value.Immutable public abstract class Person {abstract String getName (); abstrakt Heltal getAge (); }

Når annoteringsbehandlingen er færdig, kan vi finde en klar til brug, nyligt genereret Uforanderlig person klasse i en mål / genererede kilder vejviser:

@Generated ({"Immutables.generator", "Person"}) offentlig endelig klasse ImmutablePerson udvider Person {private final Strengnavn; privat endelig Heltalder; private ImmutablePerson (String name, Integer age) {this.name = name; this.age = alder; } @ Override String getName () {return name; } @ Override Integer getAge () {returalder; } // toString, hashcode, er lig, copyOf og Builder udeladt}

Den genererede klasse kommer med implementeret toString, hashcode, lige med metoder og med en stepbuilder ImmutablePerson.Builder. Bemærk, at den genererede konstruktør har privat adgang.

For at konstruere en forekomst af Uforanderlig person klasse, skal vi bruge bygherren eller den statiske metode ImmutablePerson.copyOf, som kan skabe en Uforanderlig person kopi fra en Person objekt.

Hvis vi vil konstruere en instans ved hjælp af bygherren, kan vi blot kode:

ImmutablePerson john = ImmutablePerson.builder () .age (42) .name ("John") .build ();

Genererede klasser er uforanderlige, hvilket betyder, at de ikke kan ændres. Hvis du vil ændre et allerede eksisterende objekt, kan du bruge et af “medX”-Metoder, som ikke ændrer et originalt objekt, men opretter en ny instans med et modificeret felt.

Lad os opdatere john's alder og skabe et nyt john43 objekt:

ImmutablePerson john43 = john.withAge (43); 

I et sådant tilfælde gælder følgende påstande:

hævder, at (john) .isNotSameAs (john43);
assertThat (john.getAge ()). er EqualTo (42);

4. Yderligere hjælpeprogrammer

Sådan klassegeneration ville ikke være særlig nyttig uden at være i stand til at tilpasse den. Immutables-biblioteket leveres med et sæt yderligere kommentarer, der kan bruges til tilpasning @ Value.Immutable'S output. For at se dem alle henvises til dokumentationen til Immutables.

4.1. Det @ Value.Parameter Kommentar

Det @ Value.Parameter annotation kan bruges til at specificere felter, som konstruktormetoden skal genereres til.

Hvis du kommenterer din klasse sådan:

@ Value.Immutable public abstract class Person {@ Value.Parameter abstract String getName (); @ Value.Parameter abstrakt Heltal getAge (); }

Det vil være muligt at instantiere det på følgende måde:

ImmutablePerson.of ("John", 42);

4.2. Det @ Value.Default Kommentar

Det @ Value.Default annotation giver dig mulighed for at specificere en standardværdi, der skal bruges, når der ikke angives en startværdi. For at gøre dette skal du oprette en ikke-abstrakt tilgangsmetode, der returnerer en fast værdi og kommentere den med @ Value.Default:

@ Value.Immutable public abstract class Person {abstract String getName (); @ Value.Default Integer getAge () {return 42; }}

Følgende påstand vil være sand:

ImmutablePerson john = ImmutablePerson.builder () .name ("John") .build (); assertThat (john.getAge ()). er EqualTo (42);

4.3. Det @ Value.Auxiliary Kommentar

Det @ Value.Auxiliary annotation kan bruges til at kommentere en ejendom, der vil blive gemt i et objekt, men som ignoreres af lige med, hashCode og toString implementeringer.

Hvis du kommenterer din klasse sådan:

@ Value.Immutable public abstract class Person {abstract String getName (); abstrakt Heltal getAge (); @ Value.Auxiliary abstract String getAuxiliaryField (); }

Følgende påstande gælder, når du bruger hjælp Mark:

ImmutablePerson john1 = ImmutablePerson.builder () .name ("John"). Alder (42) .auxiliaryField ("Value1") .build (); ImmutablePerson john2 = ImmutablePerson.builder () .name ("John"). Alder (42) .auxiliaryField ("Value2") .build (); 
assertThat (john1.equals (john2)). er sand ();
assertThat (john1.toString ()). er EqualTo (john2.toString ()); 
assertThat (john1.hashCode ()). er EqualTo (john2.hashCode ());

4.4. Det @ Value.Immutable (Prehash = True) Kommentar

Da vores genererede klasser er uforanderlige og aldrig kan blive ændret, hashCode Resultaterne forbliver altid de samme og kan kun beregnes en gang under objektets instantiering.

Hvis du kommenterer din klasse sådan:

@ Value.Immutable (prehash = true) offentlig abstrakt klasse Person {abstrakt String getName (); abstrakt Heltal getAge (); }

Når du inspicerer den genererede klasse, kan du se det hashcode værdi beregnes nu og lagres i et felt:

@Generated ({"Immutables.generator", "Person"}) offentlig endelig klasse ImmutablePerson udvider Person {private final Strengnavn; privat endelig Heltalder; privat endelig int hashCode; private ImmutablePerson (String name, Integer age) {this.name = name; this.age = alder; this.hashCode = computeHashCode (); } // genererede metoder @ Override public int hashCode () {return hashCode; }} 

Det hashCode () metode returnerer en forudberegnet hashcode genereret, da objektet blev konstrueret.

5. Konklusion

I denne hurtige vejledning viste vi de grundlæggende funktioner i biblioteket Immutables.

Alle kildekode og enhedstest i artiklen kan findes i GitHub-arkivet.


$config[zx-auto] not found$config[zx-overlay] not found