Java 25 ya está aquí, ya llegó

La nueva versión de Java realmente no rompe nada no rompe nada (bueno, rompe a los que aún viven en 32 bits, ¿hola? ¿Hay alguien ahí?), pero pule bastante cosillas, veamos algunas cuantas.

Constructores más flexibles

Parece mentira, pero por fin se pueden hacer cosas antes de llamar a super() o this(). Ideal para validar argumentos o preparar datos.

// Antes: obligado a llamar primero a super
class Persona {
    Persona(String nombre) { }
}

class Empleado extends Persona {
    Empleado(String nombre) {
        super(nombre); // obligatorio aquí
        // Validar o transformar después
    }
}
// Ahora en Java 25
class Empleado extends Persona {
    Empleado(String nombre) {
        if (nombre == null) nombre = "Desconocido"; // ya puedo hacerlo antes
        super(nombre);
    }
}

Al fin dejarán de burlarse de nuestro main

25 versiones después, ya no hace falta el clásico public static void main(String[] args).
Si solo quieres probar algo rápido:

// Ahora puedes escribir:
void main() {
    System.out.println("Hola Java 25");
}

Perfecto para scripts, utils o demos.

Scoped Values: adiós a los ThreadLocal

Los ThreadLocal siempre fueron un arma de doble filo: útiles, pero fáciles de olvidar y propensos a fugas.
Con Scoped Values podemos pasar valores de contexto sin tanto riesgo:

// Antes: ThreadLocal
private static final ThreadLocal<String> user = new ThreadLocal<>();

public static void main(String[] args) {
    user.set("Oscar");
    doSomething();
}

static void doSomething() {
    System.out.println("Hola " + user.get());
}
// Ahora: ScopedValue
private static final ScopedValue<String> user = ScopedValue.newInstance();

public static void main(String[] args) {
    ScopedValue.runWhere(user, "Oscar", () -> {
        doSomething();
    });
}

static void doSomething() {
    System.out.println("Hola " + user.get());
}

Más limpio, más seguro, y sin tantas fugas de memoria.

Importar módulos enteros

Con los Module Import Declarations se limpian los import:

// Antes
import java.util.List;
import java.util.Map;
import java.util.Set;

// Ahora
import module java.base;

Más corto, y si usas muchas clases de un módulo, ahorras líneas.

Rendimiento y memoria

  • Compact Object Headers: Los objetos ocupan menos en memoria (opcional con flag).
  • Generational Shenandoah: El recolector de basura Shenandoah ahora es generacional, menos pausas y más eficiencia.
  • Profiling mejorado: Java Flight Recorder ahora puede muestrear hilos de forma más precisa y ligera.

Nuevo api para Key Derivation Functions (KDFs)

Antes había que pelearse con SecretKeyFactory, PBKDF2, etc. Ahora hay una API directa y coherente.

KDF hkdf = KDF.getInstance("HKDF-SHA256");  

AlgorithmParameterSpec params =  
        HKDFParameterSpec.ofExtract()  
                .addIKM(initialKeyMaterial)  
                .addSalt(salt)
                .thenExpand(info, 32);  
SecretKey key = hkdf.deriveKey("AES", params);

El final de los 32 bits

Adiós al soporte oficial para x86 de 32 bits. Si todavía trabajas en ese tipo de máquinas… ya es hora de actualizar.

Como ves, Java 25 no trae un terremoto, pero sí una colección de mejoras que se notan en el día a día: menos código repetitivo, más APIs coherentes, mejor gestión de memoria y un GC que sigue evolucionando. Es la clase de actualización que agradeces sin darte cuenta, porque simplifica tareas comunes y te deja centrarte en lo que importa: escribir buen código sin refactorizar tanto.

Published by