Java 14 Record Keyword

1. Introduksjon

Å overføre uforanderlige data mellom objekter er en av de vanligste, men verdslige oppgavene i mange Java-applikasjoner.

Før Java 14 krevde dette opprettelsen av en klasse med kjelefelt og metoder, som var utsatt for trivielle feil og rotete intensjoner.

Med utgivelsen av Java 14 kan vi nå bruke poster for å avhjelpe disse problemene.

I denne veiledningen, vi vil se på grunnleggende poster, inkludert formålet deres,genererte metoder og tilpasningsteknikker.

2. Formål

Vanligvis skriver vi klasser for bare å holde data, for eksempel databaseresultater, søkeresultater eller informasjon fra en tjeneste.

I mange tilfeller er disse dataene uforanderlige siden uforanderlighet sikrer gyldigheten av dataene uten synkronisering.

For å oppnå dette oppretter vi dataklasser med følgende:

  1. privat, endelig felt for hvert stykke data
  2. getter for hvert felt
  3. offentlig konstruktør med et tilsvarende argument for hvert felt
  4. er lik metode som returnerer ekte for objekter av samme klasse når alle feltene samsvarer
  5. hashCode metode som returnerer den samme verdien når alle feltene samsvarer
  6. toString metode som inkluderer navnet på klassen og navnet på hvert felt og dets tilsvarende verdi

For eksempel kan vi lage en enkel Person dataklasse, med navn og adresse:

offentlig klasse Person {privat slutt Strengnavn; privat slutt streng adresse; offentlig person (strengnavn, strengadresse) {this.name = navn; denne.adressen = adresse; } @ Override public int hashCode () {return Objects.hash (navn, adresse); } @Override offentlig boolsk er lik (Objekt obj) {hvis (dette == obj) {returner sant; } annet hvis (! (obj instance of Person)) {return false; } annet {Person annen = (Person) obj; returner Objects.equals (navn, annet.navn) && Objects.equals (adresse, annet.adresse); }} @ Override public String toString () {return "Person [name =" + name + ", address =" + address + "]"; } // standard getters}

Selv om dette oppnår vårt mål, er det to problemer med det:

  1. Det er mye kokerplatekode
  2. Vi tilslører formålet med klassen vår - å representere en person med navn og adresse

I det første tilfellet må vi gjenta den samme kjedelige prosessen for hver dataklasse, og monotont skape et nytt felt for hvert stykke data, og skape er lik, hashCode, og toString metoder, og lage en konstruktør som godtar hvert felt.

Mens IDE automatisk kan generere mange av disse klassene, de klarer ikke å oppdatere klassene våre automatisk når vi legger til et nytt felt. Hvis vi for eksempel legger til et nytt felt, må vi oppdatere vårt er lik metode for å innlemme dette feltet.

I det andre tilfellet, den ekstra koden tilslører at klassen vår bare er en dataklasse som har to String Enger: Navn og adresse.

En bedre tilnærming ville være å eksplisitt erklære at klassen vår er en dataklasse.

3. Grunnleggende

Fra og med JDK 14 kan vi erstatte våre gjentatte dataklasser med poster. Postene er uforanderlige dataklasser som bare krever typen og navnet på feltene.

De er lik, hashCode, og toString metoder, samt privat, endelig felt, og offentlig konstruktør, genereres av Java-kompilatoren.

Å lage en Person , bruker vi ta opp nøkkelord:

offentlig journalperson (strengnavn, strengadresse) {}

3.1. Konstruktør

Ved hjelp av poster genereres en offentlig konstruktør - med et argument for hvert felt - for oss.

I tilfelle av vår Person rekord, tilsvarer konstruktøren:

offentlig person (strengnavn, strengadresse) {this.name = navn; denne.adressen = adresse; }

Denne konstruktøren kan brukes på samme måte som en klasse for å instantiere objekter fra posten:

Personperson = ny person ("John Doe", "100 Linda Ln.");

3.2. Getters

Vi mottar også offentlige getters-metoder - hvis navn samsvarer med navnet på feltet vårt - gratis.

I vår Person post, betyr dette en Navn() og adresse() getter:

@Test public void givenValidNameAndAddress_whenGetNameAndAddress_thenExpectedValuesReturned () {String name = "John Doe"; Strengadresse = "100 Linda Ln."; Personperson = ny person (navn, adresse); assertEquals (navn, person.navn ()); assertEquals (adresse, person.adresse ()); }

3.3. er lik

I tillegg an er lik metoden genereres for oss.

Denne metoden returnerer ekte hvis det medfølgende objektet er av samme type og verdiene for alle feltene samsvarer med:

@Test offentlig ugyldighet givenSameNameAndAddress_whenEquals_thenPersonsEqual () {String name = "John Doe"; Strengadresse = "100 Linda Ln."; Person person1 = ny person (navn, adresse); Person person2 = ny person (navn, adresse); assertTrue (person1.equals (person2)); }

Hvis noen av feltene skiller mellom to Person tilfeller, den er lik metoden vil komme tilbake falsk.

3.4. hashCode

I likhet med vår er lik metode, en tilsvarende hashCode metoden blir også generert for oss.

Våre hashCode metoden returnerer samme verdi for to Person objekter hvis alle feltverdiene for begge objektene samsvarer (sperring av kollisjoner på grunn av bursdagsparadokset):

@Test offentlig ugyldighet givenSameNameAndAddress_whenHashCode_thenPersonsEqual () {String name = "John Doe"; Strengadresse = "100 Linda Ln."; Person person1 = ny person (navn, adresse); Person person2 = ny person (navn, adresse); assertEquals (person1.hashCode (), person2.hashCode ()); } 

De hashCode verdien vil variere hvis noen av feltverdiene er forskjellige.

3.5. toString

Til slutt mottar vi også entoString metode som resulterer i en streng som inneholder postens navn, etterfulgt av navnet på hvert felt og dets tilsvarende verdi i parentes.

Instansering av en Person med navnet på "John Doe" og en adresse til “100 Linda Ln.”Resulterer i følgende toString resultat:

Person [navn = John Doe, adresse = 100 Linda Ln.]

4. Konstruktører

Mens det genereres en offentlig konstruktør for oss, kan vi fremdeles tilpasse konstruktørimplementeringen vår.

Denne tilpasningen er ment å brukes til validering og bør holdes så enkel som mulig.

For eksempel kan vi sikre at Navn og adresse gitt til vår Person er ikke null ved hjelp av følgende konstruktørimplementering:

offentlig post Person (strengnavn, strengadresse) {offentlig person {Objects.requireNonNull (navn); Objects.requireNonNull (adresse); }}

Vi kan også lage nye konstruktører med forskjellige argumenter ved å levere en annen argumentliste:

offentlig post Person (strengnavn, strengadresse) {offentlig person (strengnavn) {dette (navn, "ukjent"); }}

Som med klassekonstruktører, feltene kan refereres til ved hjelp av dette nøkkelord (for eksempel, dette.navnet og dette. adresse) og argumentene samsvarer med navnet på feltene (det er, Navn og adresse).

Noter det å lage en konstruktør med de samme argumentene som den genererte offentlige konstruktøren er gyldig, men dette krever at hvert felt initialiseres manuelt:

offentlig post Person (strengnavn, strengadresse) {offentlig person (strengnavn, strengadresse) {dette.navn = navn; denne.adressen = adresse; }}

I tillegg Å erklære en konstruktør uten argument og en med en argumentliste som samsvarer med den genererte konstruktøren, resulterer i en kompileringsfeil.

Derfor vil ikke følgende kompilere:

offentlig post Person (strengnavn, strengadresse) {offentlig person {Objects.requireNonNull (navn); Objects.requireNonNull (adresse); } offentlig person (strengnavn, strengadresse) {this.name = navn; denne.adressen = adresse; }}

5. Statiske variabler og metoder

Som med vanlige Java-klasser, vi kan også inkludere statiske variabler og metoder i postene våre.

Vi erklærer statiske variabler som bruker samme syntaks som en klasse:

public record Person (String name, String address) {public static String UNKNOWN_ADDRESS = "Ukjent"; }

På samme måte erklærer vi statiske metoder som bruker samme syntaks som en klasse:

offentlig post Person (strengnavn, strengadresse) {offentlig statisk person ikke navngitt (strengadresse) {returner ny person ("Unnamed", adresse); }}

Vi kan da referere til både statiske variabler og statiske metoder ved å bruke navnet på posten:

Person.UNKNOWN_ADDRESS Person.unnamed ("100 Linda Ln.");

6. Konklusjon

I denne artikkelen så vi på ta opp nøkkelord introdusert i Java 14, inkludert deres grunnleggende konsepter og forviklinger.

Ved hjelp av poster - med kompilatorgenererte metoder - kan vi redusere kokerplatekoden og forbedre påliteligheten til våre uforanderlige klasser.

Koden og eksemplene for denne veiledningen finner du på GitHub.