Inicio > Cursos > Java > Optional y Records (Java 14+)
JavaStrings, Arrays y MétodosLección 10 de 15

Optional y Records (Java 14+)

NullPointerException es el error más común en Java: ocurre cuando intentas usar un método o atributo de una variable que es null. Optional<T> es la solución moderna: en lugar de retornar null cuando algo no se encuentra, retornas Optional.empty(). El código que recibe el Optional es forzado a manejar el caso "no hay valor" antes de acceder al contenido. Es como una caja transparente: puedes ver si hay algo adentro antes de intentar sacarlo.

Los Records (introducidos en Java 16) son clases de datos inmutables con sintaxis ultra-concisa. En lugar de escribir 30 líneas con constructor, getters, equals, hashCode y toString, escribes una sola línea: record Persona(String nombre, int edad) {}. Java genera todo lo demás automáticamente. Los accessors se llaman igual que el campo (p.nombre() en lugar de p.getNombre()).

Son perfectos para DTOs (Data Transfer Objects), respuestas de API, y cualquier dato que no deba modificarse después de crearse.

import java.util.Optional;

// Optional - evitar null
public Optional<String> buscarEmail(String nombre) {
    Map<String, String> emails = Map.of(
        "Ana", "ana@mail.com",
        "Bob", "bob@mail.com"
    );
    return Optional.ofNullable(emails.get(nombre));
}

// Uso de Optional
Optional<String> email = buscarEmail("Ana");

// Verificar si tiene valor
if (email.isPresent()) {
    System.out.println(email.get());
}

// ifPresent - callback si hay valor
email.ifPresent(e -> System.out.println("Email: " + e));

// orElse - valor por defecto
String resultado = email.orElse("sin-email@default.com");

// orElseGet - valor por defecto con función
String resultado2 = email.orElseGet(() -> generarEmail("Ana"));

// orElseThrow - lanzar excepción si vacío
String emailSeguro = email.orElseThrow(() ->
    new RuntimeException("Usuario sin email"));

// map - transformar el valor si existe
Optional<Integer> longitud = email.map(String::length);

// filter - filtrar el valor
Optional<String> emailValido = email
    .filter(e -> e.contains("@"));

// Records (Java 16) - clases de datos inmutables
record Punto(double x, double y) {}
record Persona(String nombre, int edad) {
    // Constructor compacto con validación
    Persona {
        if (nombre.isBlank()) throw new IllegalArgumentException("Nombre requerido");
        if (edad < 0) throw new IllegalArgumentException("Edad inválida");
    }
    
    // Método de instancia
    public String presentar() {
        return nombre + " (" + edad + " años)";
    }
}

var p = new Persona("Ana", 25);
System.out.println(p.nombre()); // Ana (accessor, no getNombre)
System.out.println(p);          // Persona[nombre=Ana, edad=25]
Consejo📦 Records generan automáticamente: constructor, getters (nombre()), equals(), hashCode() y toString(). Perfectos para DTOs y datos inmutables.
← Métodos Avanzados y VarargsSealed Classes y Pattern Matching →

Practica esta lección

Resuelve los ejercicios del curso de Java en la app, gratis y con corrección automática.

Empezar a practicar