Records – JEP 359

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 and hashCode 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?

One thought on “Records – JEP 359

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.