Sealed Classes y Pattern Matching
Las Sealed classes (Java 17) solucionan un problema de diseño: cuando creas una jerarquía de clases, cualquiera puede crear subclases nuevas, lo que hace imposible escribir código exhaustivo. Con sealed class Figura permits Circulo, Rectangulo, Triangulo, defines exactamente las subclases permitidas. El compilador puede entonces verificar que un switch sobre Figura cubre todos los casos, similar a cómo TypeScript maneja discriminated unions.
Pattern matching es una de las adiciones más modernas y útiles de Java. Con instanceof clásico necesitabas verificar el tipo y luego hacer cast: if (obj instanceof String) { String s = (String) obj; ... }. Con pattern matching escribes: if (obj instanceof String s) { ... } y ya tienes s disponible como String.
El switch con pattern matching es aún más poderoso: maneja tipos complejos con "guards" (condiciones adicionales con when), haciendo el código más expresivo y seguro.
// Sealed classes (Java 17)
public sealed class Figura
permits Circulo, Rectangulo, Triangulo {}
public final class Circulo extends Figura {
public double radio;
public Circulo(double radio) { this.radio = radio; }
}
public final class Rectangulo extends Figura {
public double ancho, alto;
public Rectangulo(double ancho, double alto) {
this.ancho = ancho; this.alto = alto;
}
}
public final class Triangulo extends Figura {
public double base, altura;
public Triangulo(double base, double altura) {
this.base = base; this.altura = altura;
}
}
// Pattern matching con switch (Java 21)
double calcularArea(Figura figura) {
return switch (figura) {
case Circulo c -> Math.PI * c.radio * c.radio;
case Rectangulo r -> r.ancho * r.alto;
case Triangulo t -> (t.base * t.altura) / 2;
// El compilador sabe que estas son todas las posibilidades
};
}
// Pattern matching con instanceof (Java 16)
object procesarObjeto(Object obj) {
if (obj instanceof String s && s.length() > 0) {
return s.toUpperCase();
} else if (obj instanceof Integer i && i > 0) {
return i * 2;
} else if (obj instanceof List<?> lista) {
return lista.size();
}
return null;
}
// Guarded patterns (Java 21)
String describir(Object obj) {
return switch (obj) {
case Integer i when i < 0 -> "Entero negativo";
case Integer i when i == 0 -> "Cero";
case Integer i -> "Entero positivo: " + i;
case String s when s.isEmpty() -> "String vacío";
case String s -> "String: " + s;
case null -> "Nulo";
default -> "Otro: " + obj.getClass().getSimpleName();
};
}
Practica esta lección
Resuelve los ejercicios del curso de Java en la app, gratis y con corrección automática.
Empezar a practicar