Records in Java 14 for Concise Data Carriers
As one of the most widely used languages, Java continuously evolves to the requirements of modern, agile applications. Agile software is developed around code that is simple, concise, easy to understand, and easy to update. In this article, we explore a preview language feature in Java 14 that improves the design of data carriers, making them simple, concise, and agile.
The Problem: Java already provides the Collections framework for defining data structures. A collection is a group of objects. The Collections framework could be used to define various kinds of data structures, such as a set, queue, and list. The Collections framework is not suitable for data carriers, because Collections classes as data carriers or data aggregates require a lot of boilerplate coding when all that is needed is a class that defines the state of some data values. As an example, consider a class that is a data carrier for point data. It must include the final field declarations, constructor, accessors, and implementations of equals(), hashCode(), and toString().
The Solution: Java 14 introduces records as a concise syntax for declaring data carriers or data aggregates. The objective is to model data as data with the related benefits of a smaller code base. Records are simple, transparent holders of data. Records are a new kind of a type declaration and would introduce a new keyword called record if the experimental feature is accepted into the language. A record is declared using the record keyword and has a name and a state description. The state description declares the components of the record, the data holders. A record is identified by its state description. Similar to an enum, a record is a restricted form of a class.
How is a record different from a class? A record cannot extend another class. Records are final, which means that it cannot be extended. A record cannot declare instance fields. Only static fields may be declared. A field with the same name as a component cannot be declared. A record cannot be abstract. Components are implicitly final, which means that setting them to a different value after being constructed generates an error message.
How is a record like a class? The record’s body may declare static methods, static fields, static initializers, constructors, instance methods, and nested types. Just like a class, a record may be top-level or nested. Just like a class, a record may be generic. A record may implement interfaces.
If a record is a nested type, then it is implicitly static. A static nested record cannot directly access the instance methods of the enclosing record.
The record and the individual components in a state description may be annotated.
Any of the implicit record members, which include a private final field for each component, a public read accessor method for each component, a public constructor, implementations of equals and hashCode, and an implementation of toString(), may also be declared explicitly.
A record is a short form for a data carrier class. A record is a new type, a special kind of a Java class just as an enum is a class. In Java 15 records is still a preview language feature. Whether the records feature becomes a Java language feature depends on developer feedback. The records feature makes Java more Agile by making it simple and concise. One of the Manifesto for Agile Software Development principles is “Simplicity—the art of maximizing the amount of work not done—is essential.”