What are Java Records

Introduction

In this tutorial, we will take an in-depth look at Java records, exploring what they are, how they work, and the various ways they can be effectively utilized in real-world applications.

What do we create?

Java records are a special kind of class introduced in Java 14. They are designed to create immutable data classes with minimal boilerplate code.

Records are especially useful for classes that are primarily used to store data (often referred to as “Data Transfer Objects” or DTOs or Data classes), where the focus is on the data they hold rather than their behavior.

How do we create it?

First, we need to create a new project which is compiled with Java 14+. We do not need any building tool like Gradle or Maven because the project does not require any additional dependency or settings.

A Data Transfer Object is a simple object used to transfer data between different layers or parts of a software application. Usually, it contains some basic attributes and a lot of boilerplate code:

				
					public class LemonadeData {
    
    private String name;
    
    private Double price;

    public LemonadeDataEx(String name, Double price) {
        this.name = name;
        this.price = price;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    @Override
    public String toString() {
        return "LemonadeData{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}';
    }
}
				
			

Using the key word record, we can rewrite this class in only one line:

				
					public record LemonadeData(String name, Double price) {
}
				
			

This declaration automatically provides a constructor, getters, equals, hashcode and toString methods.

It is important to specify that the fields of a record are final by default, ensuring that the data cannot be changed after the object is created, therefore, we don’t have any setters created. 

We can create a simple Main Class to test our Data Class:

				
					public class Main {
    
    public static void main(String[] args) {
        LemonadeData lemonadeData = new LemonadeData("Sweet lemonade", 25.0);

        System.out.println("Name: " + lemonadeData.name());
        System.out.println("Price: " + lemonadeData.price());
        System.out.println("Lemonade Data: " + lemonadeData);
    }
}

				
			

And the output will be:

				
					Name: Sweet lemonade
Price: 25.0
Lemonade Data: LemonadeData[name=Sweet lemonade, price=25.0]
				
			

You can add custom methods to records, but they cannot modify the fields:

				
					public record LemonadeData(String name, Double price) {

    public String displayInfo() {
        return "The lemonade " + name + " has a price of " + price + "$. ";
    }
}
				
			

 

You can use records when you need a simple data holder class and the class doesn’t require behavior beyond the basic fields.

Records cannot extend other classes, are not suitable for mutable data and you cannot declare instance fields outside the parameter list of the record.

Conclusion

In this tutorial we discussed Java records, a feature introduced in JDK 14. We had a simple example and we exemplified some use-cases where Java records can be used.