It’s frequently that when writing our code, we end up writing “data” classes(POJO). Classes with several properties, getters and setters, equals, hash code, toString and nothing else. Of course, all the code can be generated by the IDE and more recently Lombok but they are still required and are one of the reasons for Java be called “too verbose”.
Java over the past years has been presenting the community with several additions that aim to help the developer and create an easier and more inclusive environment. Better NullPointerException messages, JShell and more recently Records (a preview feature of Java 14) are a few examples.
Records (JEP 359) are a special type of class that holds immutable data. They are intended to be simple, eliminate boilerplate and will have generated automatically:
- A private final field for each component of the state description;
- A public read accessor method for each component of the state description, with the same name and type as the component;
- A public constructor, whose signature is the same as the state description, which initializes each field from the corresponding argument;
- Implementations of
equals
andhashCode
that say two records are equal if they are of the same type and contain the same state; and - An implementation of
toString
that includes the string representation of all the record components, with their names.
Restrictions on Records
- Can’t extend another class
- Cannot declare instance fields other than the private final fields which correspond to components of the state description. All other fields MUST be static
- They are
final
- Can’t be
abstract
Declaring a Record
Before Java 14, if we want to create a POJO class with 2 properties (int age and String name), we would have at minimum the following code:
class Player { private int age; private String name; public Player(int age, String name) { this.age = age; this.name = name; } @Override public String toString() { return "Player{" + "age=" + age + ", name='" + name + '\'' + '}'; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Player player = (Player) o; if (age != player.age) return false; return name != null ? name.equals(player.name) : player.name == null; } @Override public int hashCode() { int result = age; result = 31 * result + (name != null ? name.hashCode() : 0); return result; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } }
It’s a lot of code. But now let’s see the same code using Records
:
record Player(int age, String name){}
Clean, simple and more readable.
I love this feature and believe it’s long overdue. IMHO, the community will quickly adopt it. What’s your opinion? Like, dislike?
3 thoughts on “Records – JEP 359”