Java 14 Records Klasse

Java 14 introduceerde een nieuwe manier om klassen te maken, genaamd Records. In deze tutorial zullen we leren:

  • Waarom hebben we Java Records nodig?
  • Hoe Records te maken en ze te gebruiken
  • Overrides en uitbreiding van Records-klassen

Aanbevolen lectuur: Java 14 Functies

Waarom hebben we Java Records nodig?

Een van de veelvoorkomende klachten over Java is de omslachtigheid. Als je een eenvoudige POJO-klasse moet maken, is de volgende standaardcode nodig.

  • Private velden
  • Getter- en Setter-methoden
  • Constructors
  • hashCode(), equals() en toString() methoden.

Deze omslachtigheid is een van de redenen voor de grote interesse in Kotlin en Project Lombok.

Feitelijk leidde de pure frustratie van het schrijven van deze generieke methoden telkens opnieuw tot snelkoppelingen om ze te maken in Java IDE’s zoals Eclipse en IntelliJ IDEA.

Hier is een schermafbeelding die de Eclipse IDE-optie laat zien om de ceremoniële methoden voor een klasse te genereren.

Eclipse Shortcuts to Generate Ceremonial Methods

Java Records zijn bedoeld om deze omslachtigheid te verminderen door een compacte structuur te bieden voor het maken van POJO-klassen.

Hoe Java Records te maken

Java Records is een voorbeeldfunctie, die ontwikkeld is onder JEP 359. Dus, je hebt twee dingen nodig om Records te maken in je Java-projecten.

  1. JDK 14 geïnstalleerd. Als je een IDE gebruikt, moet deze ook ondersteuning bieden voor Java 14. Zowel Eclipse als IntelliJ bieden al ondersteuning voor Java 14, dus we zitten hier goed.
  2. Activeer Voorbeeldfunctie: Standaard zijn de voorbeeldfuncties uitgeschakeld. Je kunt deze inschakelen in Eclipse via de Project Java Compiler-instellingen.
Java 14 Enable Preview Feature In Eclipse

Je kunt Java 14 voorbeeldfuncties inschakelen via de opdrachtregel met de --enable-preview -source 14 optie.

Laten we zeggen dat ik een modelklasse Employee wil maken. Het zal er ongeveer uitzien als de volgende code.

package com.journaldev.java14;

import java.util.Map;

public class Employee {

	private int id;
	private String name;
	private long salary;
	private Map<String, String> addresses;

	public Employee(int id, String name, long salary, Map<String, String> addresses) {
		super();
		this.id = id;
		this.name = name;
		this.salary = salary;
		this.addresses = addresses;
	}

	public int getId() {
		return id;
	}

	public String getName() {
		return name;
	}

	public long getSalary() {
		return salary;
	}

	public Map<String, String> getAddresses() {
		return addresses;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((addresses == null) ? 0 : addresses.hashCode());
		result = prime * result + id;
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result + (int) (salary ^ (salary >>> 32));
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Employee other = (Employee) obj;
		if (addresses == null) {
			if (other.addresses != null)
				return false;
		} else if (!addresses.equals(other.addresses))
			return false;
		if (id != other.id)
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (salary != other.salary)
			return false;
		return true;
	}

	@Override
	public String toString() {
		return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + ", addresses=" + addresses + "]";
	}

}

Pff, dat zijn meer dan 70 regels auto-generieke code. Laten we nu eens kijken hoe we een Employee Recordklasse kunnen maken, die in feite dezelfde functies biedt.

package com.journaldev.java14;

import java.util.Map;

public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
}

Wow, dit kan niet korter dan dit. Ik ben nu al dol op Recordklassen.

Laten we nu de javap opdracht gebruiken om te achterhalen wat er achter de schermen gebeurt wanneer een Record wordt gecompileerd.

# javac --enable-preview -source 14 EmpRecord.java
Note: EmpRecord.java uses preview language features.
Note: Recompile with -Xlint:preview for details.

# javap EmpRecord      
Compiled from "EmpRecord.java"
public final class EmpRecord extends java.lang.Record {
  public EmpRecord(int, java.lang.String, long, java.util.Map<java.lang.String, java.lang.String>);
  public java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int id();
  public java.lang.String name();
  public long salary();
  public java.util.Map<java.lang.String, java.lang.String> addresses();
}
# 
Java Record Class Details

# javac enablevoorbeeld bron 14 EmpRecord.java

# javap EmpRecord

Als je meer interne details wilt, voer dan het javap-commando uit met de -v-optie.

  1. A Record class is final, so we can’t extend it.
  2. # javap -v EmpRecord
  3. Belangrijke punten over Record-klassen
  4. De Record-klassen breiden impliciet de klasse java.lang.Record uit.
  5. A single constructor is created with all the fields specified in the record definition.
  6. Alle velden die zijn gespecificeerd in de recordverklaring zijn finaal.
  7. De recordvelden zijn “ondiep” onveranderlijk en zijn afhankelijk van het type. We kunnen bijvoorbeeld het veld adressen veranderen door er toegang toe te krijgen en vervolgens updates aan te brengen.

De Record-klasse biedt automatisch toegangsmethoden voor de velden. De methode-naam is hetzelfde als de veldnaam, niet zoals generieke en conventionele getter-methoden.

De Record-klasse biedt ook implementaties voor hashCode(), equals() en toString().

package com.journaldev.java14;

public class RecordTest {

	public static void main(String[] args) {
		
		EmpRecord empRecord1 = new EmpRecord(10, "Pankaj", 10000, null);
		EmpRecord empRecord2 = new EmpRecord(10, "Pankaj", 10000, null);

		Het Gebruik van Records in Java Programma
		System.out.println(empRecord1);
		
		Laten we eens kijken naar een eenvoudig voorbeeld van het gebruik van onze EmpRecord-klasse.
		System.out.println("Name: "+empRecord1.name()); 
		System.out.println("ID: "+empRecord1.id());
		
		// toString()
		System.out.println(empRecord1.equals(empRecord2));
		
		// toegang tot velden
		System.out.println(empRecord1 == empRecord2);		
	}
}

// equals()

EmpRecord[id=10, name=Pankaj, salary=10000, addresses=null]
Name: Pankaj
ID: 10
true
false

// hashCode()

Output:

Het Record object werkt op dezelfde manier als elke modelklasse, gegevensobject, enzovoort.

public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {
	
	public EmpRecord {
		if (id < 0)
			throw new IllegalArgumentException("employee id can't be negative");

		if (salary < 0)
			throw new IllegalArgumentException("employee salary can't be negative");
	}

}

Het Uitbreiden van Records Constructor

EmpRecord empRecord1 = new EmpRecord(-10, "Pankaj", 10000, null);

Soms willen we wat validaties of logging hebben in onze constructor. Bijvoorbeeld, het werknemers-ID en salaris mogen niet negatief zijn. De standaardconstructor zal deze validatie niet hebben. We kunnen een compacte constructor maken in de recordklasse. De code van deze constructor wordt geplaatst aan het begin van de automatisch gegenereerde constructor.

Exception in thread "main" java.lang.IllegalArgumentException: employee id can't be negative
	at com.journaldev.java14.EmpRecord.<init>(EmpRecord.java:9)

Als we een EmpRecord maken zoals in de volgende code:

We krijgen een runtime-uitzondering zoals:

public record EmpRecord(int id, String name, long salary, Map<String, String> addresses) {

	public int getAddressCount() {
		if (this.addresses != null)
			return this.addresses().size();
		else
			return 0;
	}
}

Kunnen Records Klassen Methoden Hebben?

Ja, we kunnen methoden creëren in records.

Maar records zijn bedoeld als gegevensdragers. We zouden het vermijden om hulpprogramma-methoden in een recordklasse te hebben. Bijvoorbeeld, de bovenstaande methode kan worden gemaakt in een hulpprogramma-klasse.

Als je denkt dat het hebben van een methode noodzakelijk is voor je Record-klasse, overweeg dan goed of je echt een Record-klasse nodig hebt?

Source:
https://www.digitalocean.com/community/tutorials/java-records-class