Wednesday, May 20, 2020

Record type in Java

JDK 14, released in March 2020, introduced records (preview language feature) which provide a compact syntax for declaring classes whose main purpose is to hold data. In records, all low-level, repetitive and error-prone code is like constructors, accessor and utlity methods such as equals(), hashCode(), toString() are automatically derived based on the record’s state description.

What will we build?


Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Exam Prep

Record declaration


Record has a name and state description. The state description declares the components of the record and optionaly a body:

record Owner(String name, String address, String city, String telephone) {}
record PetType(String name) {}
record Pet(LocalDate birthDate, PetType type, Owner owner) {}

The representation of a record is derived mechanically and completely from the state description with the following members:

◉ a private final field for each component
◉ a public read accessor method for each component, with the same name and type as the component (e.g. owner.name(), owner.address())
◉ a public constructor
◉ an implementations of equals() and hashCode()
◉ an implementation of toString().

The basic behavior is demonstrated with the below test:

class Java14RecordTests {
    @Test
    void recordAccessors() {
        var owner = new Owner("John Doe", "110 W. Liberty St.", "Madison", "6085551023");
        assertThat(owner.name()).isEqualTo("John Doe");
        assertThat(owner.address()).isEqualTo("110 W. Liberty St.");
        assertThat(owner.city()).isEqualTo("Madison");
        assertThat(owner.telephone()).isEqualTo("6085551023");
    }
    @Test
    void recordEqualsAndHashCode() {
        var pet1 = new Pet(
                LocalDate.of(2019, 1, 1), 
                new PetType("dog"), 
                new Owner("John Doe", null, null, null)
        );
        var pet2 = new Pet(
                LocalDate.of(2019, 1, 1), 
                new PetType("dog"), 
                new Owner("John Doe", null, null, null)
        );
        assertThat(pet1).isEqualTo(pet2);
        assertThat(pet1.hashCode()).isEqualTo(pet2.hashCode());
    }
    @Test
    void recordToString() {
        var pet = new PetType("dog");
        assertThat(pet.toString()).isEqualTo("PetType[name=dog]");
    }
}

Restrictions


Oracle Java Tutorial and Material, Oracle Java Certification, Oracle Java Exam Prep
Record is a restricted form of class and the restrictions are:

◉ Record cannot extend any other class
◉ Any other fields which are declared must be static
◉ The components of a record are implicitly final

Additional behavior


Apart from the above restrictions, record behave like regular class and:

◉ Record may declare instance and static methods, static fields, static initializers:

record Owner(String name, String address, String city, String telephone) {
    /* Static initializer */
    static {
        NONE = "N/A";
    }
    /* Static fields are allowed, both private and public */
    private static String NONE;
    /* Records may have static methods */
    public static Owner anOwner(String name) {
        return new Owner(name, NONE, NONE, NONE);
    }
}

◉ Record may declare constructors and also compact constructors. The compact constructor has access to the record’s components:

record Pet(LocalDate birthDate, PetType type, Owner owner) {
    /* `Compact` constructor */
    public Pet {
        requiresNotNull("birthDate", birthDate);
        requiresNotNull("type", type);
        requiresNotNull("owner", owner);
    }
     
    public Pet(LocalDate birthDate, PetType type) {
        this(birthDate, type, null);
    }
    /* Records may have instance methods */
    private void requiresNotNull(String name, Object obj) {
        if (Objects.isNull(obj)) {
            throw new IllegalArgumentException(name + " can't be null");
        }
    }
}

◉ Record can override all standard methods: equals(), hashCode(), toString()
◉ Record can implement interfaces
◉ Record can be annotated

… and more.

Related Posts

0 comments:

Post a Comment