En esta entrada vamos a ver algunas de las novedades que se han introducido en Java 16

Todos los ejemplos que serán usados en este post se pueden encontrar en mi repositorio en github

Vamos a ver las 4 novedades que más nos afectarán a la hora de desarrollar. Además de estás hay otras novedades como mejoras y librerías eliminadas.

Toda la documentación se ha sacado de la página oficial: https://jdk.java.net/16/release-notes

Records (JEP 395)

Los records son un nuevo tipo de clase en Java. Estos actúan como registros inmutables de datos y se pueden crear sin toda la «ceremonia» requerida para crear una clase normal en Java (crear getters, equals y hashcode).

Esto quiere decir que podemos crear una clase con todas sus propiedades, getters, equals y hashcode en una sola linea.

Es importante tener en cuenta que al ser registros inmutables no podemos modificar las propiedades que contienen. Por lo tanto no podemos hacer un set, por ejemplo


public record AddressRecord(String street, String postCode, String town, String country){}

Si creásemos esta misma clase en java 11 el siguiente código sería equivalente:

import java.util.Objects;

public class AddressClass {
    private String street;
    private String postCode;
    private String town;
    private String country;

    public String getStreet() {
        return street;
    }


    public String getPostCode() {
        return postCode;
    }


    public String getTown() {
        return town;
    }


    public String getCountry() {
        return country;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        AddressClass that = (AddressClass) o;
        return Objects.equals(street, that.street) && Objects.equals(postCode, that.postCode) && Objects.equals(town, that.town) && Objects.equals(country, that.country);
    }

    @Override
    public int hashCode() {
        return Objects.hash(street, postCode, town, country);
    }
}

Como podemos observar si sabemos que los datos van a ser inmutables es mucho más fácil crear un record.

Clases selladas (sealed)

Esta funcionalidad solo esta disponible en la preview de Java 16 y ya está implementada en Java 17

La idea de esta nueva funcionalidad es aumentar el control que tiene el desarrollador sobre que clases pueden implementar o extender de una determinada interfaz o clase.

Actualmente si queremos impedir que una clase pueda ser extendida podemos convertirla en una «final class», pero esto impide o si no ponemos nada cualquier clase podría extender de esta, como veis no hay un punto medio.

Por eso se ha creado esta funcionalidad, a continuación podemos ver un ejemplo de clases e interfaces selladas con animales.

Creamos una clase abstracta animal, que solo va a permitir que sea extendida por las clases «Dog» y «Cat»

public abstract sealed class Animal permits Dog, Cat {

    public abstract void eat();

}

Creamos una interfaz «Bark» que solo podrá ser implementada por la clase «Dog»

public sealed interface Bark permits Dog {

    public void bark();

}

Ahora creamos las clases «Dog» y «Cat»

public final class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("The cat is eating");
    }
}
public final class Dog extends Animal implements Bark {
    @Override
    public void bark() {
        System.out.println("Guau!!");
    }

    @Override
    public void eat() {
        System.out.println("The Dog is eating");
    }
}

Como podemos observar ambas clases deben ser creadas como clases finales. Esto es para impedir que estas clases puedan volver a ser extendidas y «rompan el sellado»

Enlace de github para descargar el proyecto