0Pricing
Java Academy · Aula

Introdução aos Registros

Declare registros como estruturas concisas e imutáveis para armazenar dados e compreenda seus membros gerados automaticamente.

Introdução aos Registros é uma aula grátis de Java Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Java Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Java Academy inclui 4 aulas no total.

Apresentando os registros

Os registros Java (Java 16 ou posterior) são uma forma concisa de declarar classes imutáveis que transportam dados. Eles geram automaticamente código repetitivo: construtor, métodos de acesso, equals, hashCode e toString.

Declarando um registro

Use a palavra-chave record, seguida pelo nome do registro e por uma lista de componentes. Cada componente se torna um campo privado e final, além de um método de acesso público.

record Point(double x, double y) {}

Point p = new Point(3.0, 4.0);
System.out.println(p.x());      // 3.0 (accessor, not getX())
System.out.println(p.y());      // 4.0
System.out.println(p);          // Point[x=3.0, y=4.0]
System.out.println(p.equals(new Point(3.0, 4.0))); // true

Membros gerados automaticamente

O compilador gera automaticamente para todo registro: construtor canônico, métodos de acesso públicos, equals(), hashCode() e toString(). Não é necessário escrevê-los manualmente.

record Product(String name, double price, int stock) {}

Product p1 = new Product("Widget", 9.99, 100);
Product p2 = new Product("Widget", 9.99, 100);

System.out.println(p1.name());          // Widget
System.out.println(p1.price());         // 9.99
System.out.println(p1.equals(p2));      // true (structural)
System.out.println(p1.hashCode() == p2.hashCode()); // true
System.out.println(p1);                 // Product[name=Widget, price=9.99, stock=100]

Os registros são imutáveis

Os componentes de um registro são final. Não é possível modificá-los depois da construção — os registros representam objetos de valor imutáveis.

record Money(long cents, String currency) {}

Money price = new Money(999, "USD");
// price.cents = 500; // Compile error — final field!

// To "update" a record, create a new one
Money discounted = new Money(price.cents() - 100, price.currency());
System.out.println(discounted); // Money[cents=899, currency=USD]

Os registros estendem apenas Object

Os registros estendem implicitamente java.lang.Record e não podem estender outras classes. Eles podem implementar interfaces.

interface Describable { String describe(); }

record Circle(double radius) implements Describable {
    public String describe() {
        return String.format("Circle with radius %.1f", radius);
    }

    public double area() {
        return Math.PI * radius * radius;
    }
}

Circle c = new Circle(5.0);
System.out.println(c.describe()); // Circle with radius 5.0
System.out.printf("Area: %.2f%n", c.area()); // Area: 78.54

Registros em coleções

Como os registros implementam corretamente equals e hashCode com base em todos os componentes, funcionam corretamente como chaves de Map e elementos de Set.

import java.util.*;

record Coordinate(int row, int col) {}

Map<Coordinate, String> grid = new HashMap<>();
grid.put(new Coordinate(0, 0), "Origin");
grid.put(new Coordinate(1, 2), "Target");

// Lookup with equal-valued record works correctly
System.out.println(grid.get(new Coordinate(0, 0))); // Origin
System.out.println(grid.get(new Coordinate(1, 2))); // Target

Set<Coordinate> visited = new HashSet<>();
visited.add(new Coordinate(3, 3));
System.out.println(visited.contains(new Coordinate(3, 3))); // true

Registros como DTOs

Os registros são ideais para Objetos de Transferência de Dados (DTOs) em APIs REST — transportam dados entre camadas sem comportamento.

record CreateUserRequest(String email, String displayName, String plan) {}

record UserResponse(long id, String email, String displayName,
                    String plan, String createdAt) {}

// Simulating a service call
static UserResponse createUser(CreateUserRequest req) {
    long id = 42L;
    return new UserResponse(id, req.email(), req.displayName(),
        req.plan(), java.time.Instant.now().toString());
}

CreateUserRequest req = new CreateUserRequest("alice@example.com", "Alice", "PRO");
UserResponse resp = createUser(req);
System.out.println(resp);

Desestruturando registros

Os registros combinam bem com correspondência de padrões. Você pode desestruturá-los em expressões switch (Java 21 ou posterior).

sealed interface Shape permits Circle, Rectangle, Triangle {}
record Circle(double radius) implements Shape {}
record Rectangle(double width, double height) implements Shape {}
record Triangle(double base, double height) implements Shape {}

static double area(Shape s) {
    return switch (s) {
        case Circle(double r)            -> Math.PI * r * r;
        case Rectangle(double w, double h) -> w * h;
        case Triangle(double b, double h) -> 0.5 * b * h;
    };
}

System.out.printf("%.2f%n", area(new Circle(5)));         // 78.54
System.out.printf("%.2f%n", area(new Rectangle(4, 6)));   // 24.00

Serialização de registros

Os registros implementam Serializable naturalmente quando são declarados para isso. Eles funcionam bem com bibliotecas JSON (Jackson, Gson) sem configuração adicional.

// With Jackson (add @JsonProperty if needed)
import com.fasterxml.jackson.databind.ObjectMapper;

record OrderSummary(String orderId, double total, String status) {}

ObjectMapper mapper = new ObjectMapper();
OrderSummary order = new OrderSummary("ORD-001", 149.99, "SHIPPED");

String json = mapper.writeValueAsString(order);
System.out.println(json);
// {"orderId":"ORD-001","total":149.99,"status":"SHIPPED"}

OrderSummary restored = mapper.readValue(json, OrderSummary.class);
System.out.println(order.equals(restored)); // true

Registros aninhados

Os registros podem conter outros registros como componentes, formando grafos de objetos imutáveis e ricos.

record Address(String street, String city, String country) {}
record Customer(long id, String name, Address address) {}

Address addr = new Address("123 Main St", "New York", "US");
Customer customer = new Customer(1L, "Alice", addr);

System.out.println(customer.name());              // Alice
System.out.println(customer.address().city());   // New York
System.out.println(customer);                    // Customer[id=1, name=Alice, address=Address[street=123 Main St, city=New York, country=US]]

Limitações dos registros

Há algumas restrições dos registros que você deve conhecer:

  • Não podem estender outras classes (estendem Record implicitamente)
  • Os componentes são sempre final — não há estado mutável
  • Não podem declarar campos de instância fora da lista de componentes
  • Não podem ser abstratos
// Records CAN have static fields and methods
record Temperature(double celsius) {
    static final double ABSOLUTE_ZERO = -273.15;

    public double toFahrenheit() {
        return celsius * 9.0/5.0 + 32;
    }

    public static Temperature fromFahrenheit(double f) {
        return new Temperature((f - 32) * 5.0/9.0);
    }
}
System.out.println(Temperature.fromFahrenheit(98.6)); // Temperature[celsius=37.0]

Verificação rápida

Quais membros o compilador Java gera automaticamente para um registro?

Recapitulação: apresentando os registros

Principais conclusões:

  • Os registros declaram objetos imutáveis que transportam dados, com pouco código repetitivo
  • Gerados automaticamente: construtor canônico, métodos de acesso, equals, hashCode e toString
  • Os componentes são final — os registros são imutáveis por projeto
  • Os registros podem implementar interfaces, mas não podem estender classes
  • São perfeitos para DTOs, objetos de valor e respostas de API
  • Funcionam corretamente como chaves de HashMap e elementos de HashSet graças à igualdade estrutural

Perguntas Frequentes

A aula “Introdução aos Registros” é grátis?

Sim — o texto completo de “Introdução aos Registros” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Java Academy, atualize para CoddyKit PRO. O curso de Java Academy inclui 4 aulas no total.

O que vou aprender em “Introdução aos Registros”?

Declare registros como estruturas concisas e imutáveis para armazenar dados e compreenda seus membros gerados automaticamente. Você pratica Java Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Java Academy?

Nenhuma experiência prévia é necessária. Java Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Introdução aos Registros”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Java Academy?

Sim. Cada aula de Java Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Introdução aos Registros
  2. Construtores Compactos e Validação
  3. Métodos Personalizados em Registros
  4. Registros versus Classes versus Lombok
← Voltar para Java Academy