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))); // trueMembros 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.54Registros 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))); // trueRegistros 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.00Serializaçã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)); // trueRegistros 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
- Introdução aos Registros
- Construtores Compactos e Validação
- Métodos Personalizados em Registros
- Registros versus Classes versus Lombok