Thumbnail image

Eleve seu código Java usando Records

8/1/2024 5-minute read

Um dos recursos mais aguardados pela comunidade Java, agora disponível para todos.

Introduzido no Java 14, Records é um tipo novo lançado para o Java.

Ele foi melhorado no Java 15 e finalizado no Java 16. Agora com a chegada oficial do Java 17, vamos conhecer um pouco mais desse recurso que ainda promete evoluir muito e ajudar bastante em nossos projetos utilizando a linguagem Java.

Da mesma forma que nós temos classes, interfaces e enumeradores, agora também temos Records. Para fazer o exemplo deste artigo, é necessário que você tenha instalado no minímo, o Java 14 na sua maquina. O exemplo a seguir foi feito utilizando a IDE da JetBrains Intellij Idea e o Java na versão 17. Todo o código mostrado neste exemplo está neste repositório do GitHub, clone o projeto ou fique a vontade para construir o projeto do zero junto com o artigo.

Então vamos lá, após clonar o projeto, no Intellij, temos um novo projeto com o nome java_17. Na pasta /src vamos clicar com o botão direito do mouse ou usar o atalho ctrl + n para criar uma nova classe java. Como podemos ver, além de class, Interface, Enum e Annotation já aparece a opção Record. Vamos selecionar essa opção e daremos o nome para essa Record de Cliente.

image

caixa de dialogo

Logo após isso, a IDE irá gerar uma classe(record) simples assim.

public record Cliente() {
}

Podemos reparar que temos um parenteses “( )” logo após o nome da record. Esse parenteses funciona quase que como um Construtor. Isso quer dizer, que dentro desse parenteses, nós podemos colocar todas as propriedades que queremos para essa “classe”, no caso, para essa record. Então vamos adicionar paramêtros para a nossa record. Ela ficará assim.

public record Cliente(Long id, String nome, String telefone) {
}

Para efeito de exemplo. E para termos um idéia do benefício que uma record nos dá. Vamos criar uma classe que não seja um tipo record.

Faremos o mesmo procedimento anterior, no diretório src/ vamos clicar com o botão direito do mouse ou usar o atalho ctrl + n para criar uma nova classe java, vamos dar o nome de Cliente2.

Agora vamos criar as propriedades dessa classe.

	public class Cliente2 {
		
		private Long id;
		private String nome;
		private String telefone;
	}

Em seguida, vamos criar o construtor com todos os argumentos dessa classe. No intellij temos o atalho alt + insert. Selecione constructor, marque todos os argumentos.

image

propriedades selecionadas

E ficamos assim,

	public class Cliente2 {
		
		private Long id;
		private String nome;
		private String telefone;
	}

	public Cliente2(Long id, String nome, String telefone) {
		this.id = id;
		this.nome = nome;
		this.telefone = telefone;
	}

Vamos continuar criando nossa classe, agora vamos gerar os getters. Vamos repetir o mesmo processo alt + insert. Selecione Getter, escolha todos os atributos. Seguindo o mesmo processo, vamos gerar os equals and HashCodes. Vamos gerar também o método To String.

Bom, como podemos conferir, criamos uma classe que declaramos apenas 3 propriedades, todas elas privadas. Colocando os Contrutores, os métodos getters, equals and HashCode e mais o To String, temos uma classe com quase 50 linhas de código e não colocamos nenhuma lógica sequer, apenas o básico de uma classe.

Podemos perceber que as records são um grande atalho para criar uma classe. Quando o Java compilar essa Record, nós teremos uma classe Cliente que extends um tipo novo do Java que se chama Record. As Records não podem estender (extends) nenhuma outra classe, porém nós podemos implementar, quaisquer outras interfaces que forem necessárias. Outra coisa importante, Records por padrão são imutáveis. Isso significa que todos os atributos declarados dentro de uma Record, são Final. Então para exemplificar, vamos reproduzir isso na nossa classe Cliente2. Ficará assim:

	public class Cliente2 {
		
		private final Long id;
		private final String nome;
		private final String telefone;
	}

	public Cliente2(Long id, String nome, String telefone) {
		this.id = id;
		this.nome = nome;
		this.telefone = telefone;
	}

E é por isso, que nós temos apenas o construtor com todos os atributos e não temos um construtor vazio em uma Record. Isso também nos leva a concluir que uma Record também não possui métodos Setters, como os atributos não podem ser modificados, não podemos fazer um ‘set’ em nenhum dos atributos de uma Record. Outra coisa que precisamos ficar atentos quando utilizamos uma Record é a mudança da sintaxe nos métodos getters. Por padrão, os métodos getters de uma Record não possuem a convenção get antes do atributo. Seria algo como mostrado abaixo:

    public Long Id() {
        return id;
    }

    public String Nome() {
        return nome;
    }

    public String Telefone() {
        return telefone;
    }

Como podemos ver, temos agora uma classe(Record) de apenas uma linha, que nos economizou mais de 40 linhas de código. Mas você deve estar se perguntando, sem a convenção get, como vamos utilizar essa classe?

Vamos lá, vamos criar uma classe Main, criaremos primeiro um método e dentro desse método vamos instanciar nossa record. Agora vamos chamar o método dentro do nosso método main. A classe ficará assim:

image

Main class java

Agora vamos rodar a aplicação, no Intellij ctrl + shift + f10 e vejamos a saída no terminal.

image

saída do terminal

Como podemos ver na saída do terminal, nem precisamos criar o método to string, a saída já vem formada com a implementação do to string. Para nível de informação, vamos recapitular, uma record é uma classe que extends a classe record e por isso não podemos estender (extends) outras classes. Mas podemos implementar interfaces e também declarar métodos dentro dela, abaixo veja uma record com implementação e método.

	import java.io.Serializable;

	public record Cliente(Long id, String nome, String telefone) implements Serializable {
	    public static int COUNT = 0;

	    public void meuMetodo() {}
	}

Bom, vimos as vantagens desse novo tipo chamado Record que promete nos ajudar muito em nossas aplicações. Mas precisamos ficar atentos para algumas limitações. Como todos os atributos são final, como não temos Construtor vazio e não temos também métodos Setters, nós não conseguimos utilizar Records com o Hibernate e o JPA. Se você ficou se perguntando, então como podemos utilizar uma Record com Spring e Spring Boot? Fique atento, porque essa pergunta será respondida em breve em um novo artigo. Espero que tenha gostado, aproveite e compartilhe o artigo com seus amigos desenvolvedores e comente o que a achou das Records.