A Java 16 újdonságai

Népszerű sorozatunk új részében a Java 16 legfontosabb újdonságait vesszük górcső alá. Sorozatunk előző részét itt találod meg. Ha egy cikkben szeretnéd látni minden egyes Java verzió újdonságait a Java 4-től kezdve, ide kattintva tudod megnézni. Lássunk is neki mai témánknak!

Rekordok – végleges verzió

A rekordok a Java 14-ben jelentek meg előzetes, azaz preview feature-ként. A Java 16-ra előálltak a production-ready verzióval. A Java 16 legfontosabb újdonsága az átlagos fejlesztő számára kétségkívül ez.

Mik is azok a rekordok?

A rekordok (records) immutable adatok tárolására és átadására írt class-ok, amik rengeteg úgynevezett boilerplate kód írásától megszabadítanak minket.

Ahhoz tehát, hogy megértsük, mire jók a rekordok, meg kell tanulnunk egy új programozástechnikai fogalmat: az immutabilitást (immutability). Az immutabilitás azt jelenti, hogy egy objektum létrehozása után annak állapota (vagyis a benne tárolt adatok) többé nem módosítható. Ha egy objektum immutábilis, nem lehet megváltoztatni annak értékeit; minden módosítás helyett egy új objektumot kell létrehozni.

Például a Java-ban a String osztály immutábilis, ami azt jelenti, hogy ha egy String értékét meg akarod változtatni, valójában egy új String objektum jön létre az úgynevezett String pool-ban, nem pedig a meglévő módosul. Az immutabilitás előnyei közé tartozik a biztonság, a könnyebb hibakeresés és a párhuzamos programozásban való megbízhatóság, mivel nem kell attól tartani, hogy több szál módosítja ugyanazt az objektumot.

Igaz, hogy korábban ott volt a Lombok hasonló problémák megoldására, de nagy különbség van aközött, amikor valami a Java inherens része, illetve amikor egy külső könyvtárban valósul meg. A rekordok egy olyan igényt hivatottak kielégíteni, ami régóta sokak által tematizált volt a programozás világában.

Érdekel, mi az a Lombok?

Azért vagyunk, hogy segítsünk.

Mi volt a rekordok előtt?

A rekordok megjelenése előtt egy immutable adatok tárolására használt class-t a következőképp írhattunk le a Java beépített feature-eivel:

import java.util.Objects;

public class Person {
private final String name;
private final String surname;
private final int age;
private final String address;

public Person(String name, String surname, int age, String address) {
this.name = name;
this.surname = surname;
this.age = age;
this.address = address;
}

public String getName() {
return name;
}

public String getSurname() {
return surname;
}

public int getAge() {
return age;
}

public String getAddress() {
return address;
}

@Override
public boolean equals(Object o) {
//generáld le automatikusan az IDE segítségével
}

@Override
public int hashCode() {
//generáld le automatikusan az IDE segítségével
}
}

Többet tanulnál?

Azért vagyunk, hogy segítsünk.

Azt látjuk, hogy ez az osztály emberek reprezentálására szolgál. Természetesen azt, hogy az egyes sorok mit jelentenek, elsőre nehéz értelmezni, ezeknek a megértése kurzusainkban hatalmas jelentőséget tulajdonítunk. A junior kurzusunk második negyedévében az objektumorientáltsággal foglalkozunk, és ott részletesen vesszük az osztályokat, a rekordokat, illetve az úgynevezett sealed class-okat, amikről bővebben a Java 15 újdonságairól szóló posztunkban írtunk.

Hogy néz ki mindez rekordokkal?

import java.util.Objects;

public record Person(String name, String surname, int age, String address) {
 person.surname)
}

Ugye, mennyivel egyszerűbb?

Rekordok vagy Lombok?

Ha gyakorlott fejlesztő vagy, és az iparban dolgozol, biztosan többször feltetted már a kérdést, mikor használj rekordokat, és mikor használd a Lombok által biztosított annotációkat és funkciókat. Java-t és Spring Boot-ot is oktatunk, és ezt a témát az alacsonyabb és a magasabb szintű óráinkon is érintjük.

Alapvető különbségek

Az egyik oldalról megvizsgálva látjuk, hogy a rekordok tökéletes módszert szolgáltatnak arra, hogy rengeteg boilerplate kódtól megszabaduljunk, viszont ezt a Lombok @Data (ez final field-ekkel immutable class-t eredményez) illetve @Value (ez utóbbi immutable) annotációi is tudják. Sőt, ezen kívül a Lombok keretrendszer sokkal több dologra képes. Lombokkal például ha olyan az architektúránk, egy @Builder annotációval tudjuk a builder pattern-t implementálni, míg a rekordoknál ilyen lehetőség nincs. Egy másik példa az @Slf4j annotáció, ami automatikusan egy logger field-et generál az adott class-nak.

Másrészt a rekordok olyan esetre lettek tervezve, amikor minden egyes field-hez public getter-eket szeretnénk. Természetesen trükközéssel meg lehet oldani, hogy ne legyenek elérhetőek ezek a metódusok vagy ne azt csinálják, mint amit eredetileg hivatottak (lásd: Java modulok, Reflection API, overriding), de ebben az esetben a rekordok egyik legalapvetőbb kritériumát szegjük meg, és nem rekordokra, hanem sima class-okra van szükségünk.

Legenerált metódusok

A Lombok egy komplex framework, és a legenerált metódusok teljes egészében testre szabhatóak attól függően, hogy milyen annotációt használunk. Külön-külön el tudjuk mondani, hogy getter-eket (@Getter), setter-eket (@Setter), equals-t és hash code-ot (@EqualsAndHashCode), toString-et (@ToString), és milyen típusú konstrukturokat szeretnénk generálni. Külön van olyan annotáció, ami egy adott field-nek nem engedi meg, hogy null legyen, és rengeteg egyéb funkciója is van, amikről most nem beszélünk.

A record ezzel szemben automatikusan legenerálja az equals()-t, a hashCode()-ot, a toString()-et, és az accessor (getter) metódusokat, és sokkal kevésbé testre szabható. Ez abszolút nem gond, mert rengeteg olyan helyzet van, amikor pont ezt szeretnénk.

Performancia

Nem olvastam olyan konkrét mérési eredményeket, amik a rekordok vs Lombok témakörben meggyőző adatokkal szolgálnának, ahhoz, hogy konkrét győztest nevezzek itt ki, de ha van különbség a performanciában, akkor biztosan a rekordok javára (vagy Java-ra haha :D) a JVM-ben való optimalizációk miatt.

A győztes pedig…

Mindkettő és egyik sem – helyzettől függ, hogy melyiket használjuk. Amikor kizárólag immutabilitásra van szükségünk, nem szeretnénk sok dolgot testre szabni, nem szeretnénk logging-ot és builder pattern-t, akkor a rekordok szimpla és könnyen érthető megoldásként sokszor jobbnak bizonyulnak. Ha nem érdekes az immutabilitás, szeretnénk setter-eket, vagy fontos az immutabilitás, de szeretnénk pl. builder pattern-t, akkor a Lombok tűnik jobb választásnak.

A programozásban nagyon fontos ismerni az általunk használható eszközöket, és tudnunk kell árnyaltan gondolkozni, amikor kiválasztjuk, melyiket használjuk. Junior kurzusunkban és magasabb szintű, pl. Spring Boot-ot oktató képzésünknél is nagy jelentőséget tulajdonítunk annak, hogy ezek a készségek kialakuljanak, illetve tovább fejlődjenek.

Pattern matching

Ez a Java 16 másik legfontosabb újítása a számos egyéb mellett. Az összes Java 16-os feature listáját itt tekintheted meg, de praktikus szempontból ez a másik legfontosabb számunkra.

A Java 16-ban bevezetett mintaillesztés (pattern matching) egy egyszerűsített módja annak, hogy egy objektum típusát ellenőrizzük, és ha egyezik, akkor közvetlenül hozzárendeljük azt egy változóhoz.

Hogy néz ki a pattern matching?

public class PatternMatchingExample {
  public static void main(String[] args) {
    Object obj = "Ez egy string";    
      if (obj instanceof String s) {
        System.out.println("Az objektum egy szöveg: " + s);
      } else {
        System.out.println("Az objektum nem egy szöveg.");
    }
  }
}

A fenti példa mutatja, hogy ha az obj változó egy String példány, akkor az instanceof ellenőrzésen belül azonnal egy új változóban (s) kapjuk meg az értéket, ahelyett, hogy cast-olnunk kéne. Korábban a belső logikát így kellett volna megírni (a Main osztályunk és a main metódus kihagyása mellett):

if (obj instanceof String) {
  String s = (String) obj; // itt egy példa a cast-olásra, ami korábban megtörtént
  System.out.println("Az objektum egy szöveg: " + s);  
} else {
  System.out.println("Az objektum nem egy szöveg" + s);
}

Egy többágú elágazásnál az eredmény még látványosabb. A pattern matching-gel, azaz mintaillesztéssel tehát elkerültük a cast-olást ás a kód olvashatóbbá vált.

Ne ijedj meg – a Java is egy nyelv. Ha még nem ismered ezt a nyelvet, akkor a nyelv elsőre konfúz és nehezen érthető lehet, de azért vagyunk, hogy segítsünk neked, akár ingyenes YouTube-videóinkkal, akár kurzusainkkal.

Várunk téged a következő Java újdonságokról szóló epizódunkban!

Szerző: Nagy Csongor