Desenvolvimento Back-end Java

Conheça o recurso de Records no Java

Neste artigo, vamos aprender sobre o recurso de Records no Java. Veremos como utilizar esse recurso, suas vantagens e desvantagens.

há 11 meses 3 semanas

Formação Desenvolvedor Java
Conheça a formação em detalhes

O Java é uma linguagem bastante conhecida pela sua verbosidade, e isso é um fato. Mas, com o passar dos anos, a linguagem vem ganhando novos recursos que tornam o código mais conciso e legível. Além disso, também existem bibliotecas que ajudam a diminuir a quantidade de código que precisamos escrever. Uma dessas bibliotecas é o Lombok. Neste artigo, vamos conhecer um recurso do Java que é bastante útil e foi introduzido no Java 14: os Records.

Java - Fundamentos
Curso Java - Fundamentos
Conhecer o curso

O que são Records?

Os Records são uma nova forma de declarar classes no Java. Eles são imutáveis por padrão, o que significa que não podemos alterar seus valores após a criação do objeto. Além disso, eles são bastante úteis para representar dados, como, por exemplo, uma entidade de banco de dados.

Esse recurso foi introduzido no Java 14 como experimental, e a partir do Java 16 foi marcado como estável. Isso significa que podemos utilizá-lo em nossos projetos sem medo de que ele seja removido em uma versão futura do Java.

Quais as vantagens e desvantagens de utilizar Records?

O recurso de Records no Java nos dá algumas vantagens, como, por exemplo:

  • Sintaxe mais concisa: Records permitem definir classes de dados imutáveis de forma mais concisa, eliminando a necessidade de escrever o código repetitivo que normalmente é necessário para definir uma classe Java.
  • Redução de código boilerplate: Como os Records fornecem métodos padrão, como equals(), hashCode() e toString(), eles reduzem a quantidade de código boilerplate necessário para definir uma classe Java.
  • Imutabilidade: Como os Records são imutáveis por padrão, eles fornecem uma maneira mais segura e fácil de trabalhar com dados imutáveis.
  • Mais fácil de ler e manter: A sintaxe simplificada do Records torna mais fácil de ler e manter o código, pois é mais fácil de entender a intenção do código.
  • Melhor compatibilidade com APIs existentes: Os Records foram projetados para serem compatíveis com as APIs existentes, permitindo que os desenvolvedores usem Records em conjunto com outras classes Java sem problemas.

Por outro lado, eles também possuem algumas desvantagens, como, por exemplo:

  • Restrições na personalização de métodos: Por padrão, os Records fornecem métodos padrão, como equals(), hashCode() e toString(), que não podem ser personalizados. Embora seja possível fornecer uma implementação personalizada desses métodos, isso pode ser menos conveniente do que simplesmente estendê-los ou anulá-los em uma classe normal.
  • Limitações na herança: Os Records não suportam herança de classe, o que significa que não é possível estender um Record em outra classe. Isso pode ser um problema se você precisar adicionar funcionalidade a uma classe Record existente.
  • Maior complexidade em casos complexos: Em casos complexos, os Records podem se tornar mais difíceis de entender e manter do que as classes Java normais, devido a uma sintaxe mais compacta e a recursos específicos que podem ser difíceis de entender.
  • Restrições de visibilidade: a visibilidade dos campos e métodos em um record é limitada. Todos os campos são automaticamente finais e privados, e os métodos são todos públicos.

Como declarar um Record?

Para declarar um Record, precisamos utilizar a palavra-chave record seguida do nome da classe. Em seguida, devemos declarar os campos que o Record terá, declarados como se fossem variáveis locais. Por fim, devemos declarar o construtor da classe, declarado como se fosse um método. Veja o exemplo abaixo:

public record Person(String name, int age) {}

No exemplo acima, criamos um Record chamado Person que possui dois campos: name e age. O Record acima é equivalente à classe abaixo:

public class Person {

    private final String name;

    private final int age;

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        result = prime * result + age;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Person other = (Person) obj;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (age != other.age)
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
}

Como podemos ver, o recurso de Records no Java diminui bastante a quantidade de código que precisamos escrever para criar uma classe.

Como acessar os campos de um Record?

Java - Orientação a objetos
Curso Java - Orientação a objetos
Conhecer o curso

Para acessar os campos de um Record, podemos utilizar os métodos get() que são gerados automaticamente. Veja o exemplo abaixo:

public class Main {

    public static void main(String[] args) {
        Person person = new Person("John", 30);
        System.out.println(person.name());
        System.out.println(person.age());
    }

}

Aqui podemos ver uma particularidade dos Records, os métodos acessores são gerados com o mesmo nome dos campos, ou seja, não precisamos utilizar o prefixo get para acessar os campos. Além disso, os métodos assessores são gerados como public, o que significa que podemos acessá-los de qualquer lugar.

Customizando construtores

Por padrão, os Records geram um construtor público com todos os campos como parâmetros. No entanto, podemos personalizar o construtor de um Record. Geralmente isso é feito para aplicar validações nos campos do Record. Veja o exemplo abaixo:

public record Person(String name, int age) {

    public Person {
        if (name == null) {
            throw new IllegalArgumentException("Name cannot be null");
        }
        if (age < 0) {
            throw new IllegalArgumentException("Age cannot be negative");
        }
    }

}

No exemplo acima, criamos um construtor personalizado para o Record Person. Nesse construtor, verificamos se o nome é nulo e se a idade é negativa. Caso seja, lançamos uma exceção.

Também podemos criar mais de um construtor para um Record, por exemplo, podemos criar um construtor que recebe apenas o nome e define a idade como 0. Veja o exemplo abaixo:

public record Person(String name, int age) {

    public Person(String name, int age) {
        this(name, age);
    }

    public Person(String name) {
        this(name, 0);
    }

}

No exemplo acima, criamos dois construtores personalizados para o Record Person. O primeiro construtor recebe o nome e a idade como parâmetros e o segundo construtor recebe apenas o nome como parâmetro. No segundo construtor, definimos a idade como 0.

É importante observar que a sintaxe que utilizamos no primeiro exemplo para criar um construtor personalizado difere da sintaxe que utilizamos no segundo exemplo. A do primeiro exemplo é chamada de construtor compacto.

Onde utilizar Records?

Spring Framework - Fundamentos
Curso Spring Framework - Fundamentos
Conhecer o curso

Os Records são uma ótima opção para representar dados, como, por exemplo, DTOs (Data Transfer Objects). Além disso, eles são uma ótima opção para representar dados que não precisam ser alterados após a criação do objeto, como, por exemplo, configurações de aplicação.

Um ponto importante a se considerar é que os Records não são uma boa opção para representar entidades de banco de dados, pois eles não suportam herança, o que significa que não é possível estender um Record em outra classe. Além disso, pelo fato de os Records serem imutáveis por padrão, eles não podem ser utilizados para representar entidades da JPA (Java Persistence API), pois a JPA necessita de entidades mutáveis.

Conclusão

Neste artigo, vimos como utilizar o recurso de Records no Java. O recurso de Records no Java nos permite criar classes de dados imutáveis de forma mais concisa, eliminando a necessidade de escrever o código repetitivo que normalmente é necessário para definir uma classe Java.

Além disso, eles também nos dão algumas vantagens, como, por exemplo, uma sintaxe mais concisa, redução de código boilerplate, imutabilidade, mais fácil de ler e manter, e melhor compatibilidade com APIs existentes. Por outro lado, eles também possuem algumas desvantagens, como, por exemplo, restrições na personalização de métodos, limitações na herança, maior complexidade em casos complexos, e restrições de visibilidade.

Caso queira aprender mais sobre o Java, saiba que aqui na TreinaWeb nós temos a formação Desenvolvedor Java que possui 91h15 de vídeo e um total de 484 exercícios.

Veja quais são os cursos que fazem parte desta formação:

  • Java - Fundamentos
  • Java - Configurando o VS Code
  • Java - Orientação a objetos
  • Java - Algoritmos - Parte 1
  • Java - Estrutura de dados - Parte 1
  • Java - Estrutura de dados - Parte 2
  • Java - Collections - Parte 1
  • Java - Collections - Parte 2
  • Java - Stream API
  • XML Completo
  • XSLT Completo
  • Java - Fundamentos de JavaFx
  • Projeto de Banco de dados - Fundamentos
  • MySQL - Desenvolvedor
  • Oracle - Desenvolvedor
  • Java - Banco de dados e JDBC
  • Java - Arquivos e I/O API
  • Java - Introdução à JPA
  • Java - Fundamentos para Web
  • Java - Fundamentos de Struts 2
  • Java - Fundamentos de JAX-WS e JAX-RS
  • Java - Testes unitários com JUnit 5
  • HTTP - Fundamentos para desenvolvedores
  • Java - Consumindo APIs

Autor(a) do artigo

Cleyson Lima
Cleyson Lima

Professor, programador, fã de One Piece e finge saber cozinhar. Cleyson é graduando em Licenciatura em Informática pelo IFPI - Campus Teresina Zona Sul, nos anos de 2019 e 2020 esteve envolvido em vários projetos coordenados pela secretaria municipal de educação da cidade de Teresina, onde o foco era introduzir alunos da rede pública no mundo da programação e robótica. Hoje é instrutor dos cursos de Spring na TreinaWeb, mas diz que seu coração sempre pertencerá ao Python.

Todos os artigos

Artigos relacionados Ver todos