Menu
Coddy logo textTech

Records (Java 16+)

Parte de la sección Programación Orientada a Objetos del Journey de Java de Coddy. Lección 51 de 87.

Al crear clases sencillas que contienen datos, a menudo escribes código repetitivo: campos privados, un constructor, getters, toString(), equals() y hashCode(). Java 16 introdujo los registros para eliminar esta tediosa tarea.

Un record es una clase especial diseñada para contener datos inmutables. Se declara con la palabra clave record seguida de la lista de componentes:

record Person(String name, int age) { }

// Esa única línea proporciona automáticamente:
// - campos private final: name y age
// - un constructor: Person(String name, int age)
// - métodos de acceso: name() y age()
// - toString(), equals() y hashCode()

Usar un record es sencillo:

Person p = new Person("Alice", 30);
System.out.println(p.name());    // Alice
System.out.println(p.age());     // 30
System.out.println(p);           // Person[name=Alice, age=30]

Observa que los métodos de acceso no usan el prefijo get: simplemente reciben el nombre de los campos. Los registros son implícitamente final, por lo que no se pueden extender. Todos los campos también son final, lo que hace que los registros sean inmutables por naturaleza.

Puedes añadir métodos personalizados y sobrescribir los generados automáticamente si es necesario. También puedes añadir validación en un constructor compacto:

record Person(String name, int age) {
    public Person {
        if (age < 0) throw new IllegalArgumentException("Age cannot be negative");
    }
}

Los registros son perfectos para DTO, respuestas de API o cualquier situación en la que necesites un contenedor de datos simple e inmutable sin escribir código repetitivo.

challenge icon

Desafío

Fácil

Construyamos un sistema de reserva de entradas de cine que muestre la elegancia de los registros de Java. Verás cómo los registros eliminan el código repetitivo y, al mismo tiempo, te permiten añadir métodos personalizados y validación.

Organizarás tu código en tres archivos:

  • Movie.java: Crea un registro que represente una película con tres componentes: title (String), genre (String) y durationMinutes (int). Añade un método personalizado llamado getFormattedDuration() que devuelva la duración en un formato sencillo: [hours]h [minutes]m (por ejemplo, 142 minutos se convierten en 2h 22m). Usa la división entera y el módulo para calcular las horas y los minutos restantes.
  • Ticket.java: Crea un registro que represente una entrada de cine con tres componentes: movie (Movie), seatNumber (String) y price (double). Añade un constructor compacto que valide el precio; si el precio es menor o igual que cero, lanza una IllegalArgumentException con el mensaje Price must be positive. Añade también un método personalizado llamado printTicket() que devuelva una cadena multilínea:
    ========== TICKET ==========
    Movie: [movie title]
    Genre: [movie genre]
    Duration: [formatted duration from movie]
    Seat: [seatNumber]
    Price: $[price]
    ============================
  • Main.java: ¡Integra tu sistema de reservas! Recibirás cinco entradas: título de la película (String), género (String), duración en minutos (int), número de asiento (String) y precio de la entrada (double).

    Crea un registro Movie con las tres primeras entradas y, después, crea un registro Ticket con la película, el número de asiento y el precio. Imprime el resultado de llamar a printTicket() en tu entrada.

Recibirás cinco entradas en este orden: título de la película, género, duración (minutos), número de asiento y precio.

Observa cuánto más limpios son los registros en comparación con las clases tradicionales: no es necesario escribir constructores, getters, toString(), equals() ni hashCode(). El constructor compacto te permite añadir validación sin repetir las asignaciones de campos, y aun así puedes añadir métodos personalizados cuando sea necesario.

Pruébalo tú mismo

import java.util.Scanner;

class Main {
    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        
        // Leer entradas
        String title = scanner.nextLine();
        String genre = scanner.nextLine();
        int durationMinutes = Integer.parseInt(scanner.nextLine());
        String seatNumber = scanner.nextLine();
        double price = Double.parseDouble(scanner.nextLine());
        
        // TODO: Crea un record Movie con title, genre y durationMinutes
        
        // TODO: Crea un record Ticket con movie, seatNumber y price
        
        // TODO: Imprime el ticket usando el método printTicket()
        
    }
}
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación Orientada a Objetos

Practica por tu cuenta: Compilador de Java online