Vad är Java Records?

16 juni 2021

Tags
java

Så här kommer du igång med att använda Records i Java 16.

Java version 16, som släpptes i mars, bjöd på en riktigt stor syntaktisk nyhet, nämligen Records. I korthet, är det oföränderliga (immutable) klasser med förenklad syntax och automatgenererade åtkomst (access) metoder.

Så, vad är då vitsen med detta då? Reflektera över hur många värdeförmedlande klasser du skrivit. Du vet, en klass med en handfull medlemsvariabler som får värden i en konstruktor med lika många parametrar, lika många getter-metoder, en toString() method och equals() och hashCode() metoder kopplade värdemässigt till varandra. Typiska metoder man låter en IDE generera.

Syntax

Med records i Java 16 kan du fokusera på det väsentliga, nämligen medlemsvariablerna (properties) och låta kompilatorn ta hand om resten.

record Person(String name, int age) {}

Det som är helt nytt i syntaxen ovan, är att du deklarerar medlemsvariablerna inom parenteser. Fortsättningsvis, använder jag jshell för att visa kod-fragment och utskrifter.

$ jshell
|  Welcome to JShell -- Version 16.0.1
jshell> record Person(String name, int age) {}
|  created record Person

Instansiering är dock på klassiskt vis med new. Notera också nedan, att kompilatorn genererat getters för medlemsvariablerna.

jshell> var p = new Person("Nisse Hult", 42);
p ==> Person[name=Nisse Hult, age=42]

jshell> System.out.printf("%s, %d %n", p.name(), p.age());
Nisse Hult, 42

Auto-Metoder

Förutom getters, så genereras också toString samt equals & hashCode metoder.

jshell> System.out.println(p.toString());
Person[name=Nisse Hult, age=42]
jshell> var q = new Person("Nisse Hult", 42);
q ==> Person[name=Nisse Hult, age=42]
jshell> System.out.println(p.equals(q));
true
jshell> System.out.println(q.hashCode());
-296696321

Restriktioner

Det finns dock en del restriktioner att vara observant på. Records kan varken vara subklass eller superklass, ej heller abstrakt. Det går inte att deklarera ytterligare instansvariabler inuti record-kroppen.

Emellertid, kan en record innehålla static variabler och static metoder, samt ett static init-block (klasskonstruktor). Vidare, så kan en record implementera interface och vara generisk. Det går också att annotera en record.

Omdefinition av Getters

Det är möjligt att omdefiniera (override) en eller flera getter, för att transformera det värde som ska returneras. Tänk på att en record är immutable, så det finns inga setters att göra override på.

record Person(String name, int age) {
  public String name() {
    return name.toUpperCase();
  }
}

Förenklad Konstruktor

Behöver man kontrollera indata då en record skapas kan man deklarera en syntaktisk förenklad konstruktor, (compact constructor). I denna lägger man enbart verifieringskod. Den klassiska värdekopierings-koden (this.var = var) genereras av kompilator. Observera att denna form av konstruktor saknar parameter-parenteser!

record Person(String name, int age) {
  public Person {
    if (age < 0) 
      throw new IllegalArgumentException("Negative age: " + age);
  }
}

Inner & Local Records

Precis som man kan deklarera klasser inuti en annan klass (inner), samt inuti en metod (local), så kan man göra detta också för en record.

I praktiken, är det sällan man skapar lokala klasser, eftersom antalet kodrader i omslutande metod skulle bli för stort. Med en record deklaration på en kodrad, blir det betydligt mer användbart att skapa hjälptyper som kan aggregera värden under någon form av sammanställning i en stream pipeline.

Installation av Java 16

Enklaste sättet att installera Java och snabbt kunna växla mellan olika versioner är att använda SDKMAN i ett BASH fönster, såsom t.ex. GIT-BASH. Först installerar man SDKMAN

curl -s "https://get.sdkman.io" | bash

Sen, installerar man önskad Java version

sdk install java 16.0.1.hs-adpt
java --version

Alternativt, laddar man ned en installer från AdoptOpenJDK.

Mer om Modern Java

Vill du lära dig mer om Modern Java, dvs alla nyheter sedan Java version 8. Såsom, lambda expressions, stream pipelines, async computations, modules, records, switch expressions, med mera. Så ska du boka in dig på vår kurs Modern Java, från version 8.

Länkar