Massimo Caliman
by Massimo Caliman
3 min read

Categories

  • Java

Tags

  • code
  • it
  • java
  • updates

Il 16 settembre 2025 è stato rilasciato ufficialmente JDK 25, la nuova versione con supporto a lungo termine (LTS) di Java. Questo rilascio rappresenta una pietra miliare importantissima per l’ecosistema, consolidando molte delle anteprime introdotte nelle versioni recenti e portando notevoli miglioramenti sul fronte della sintassi del linguaggio, delle prestazioni della JVM e dell’efficienza della memoria.

In questo articolo esploreremo le novità più significative introdotte in JDK 25 che ogni sviluppatore Java dovrebbe conoscere.


1. Semplificazione del Linguaggio: Compact Source Files (JEP 512)

Uno degli ostacoli storici per chi si avvicina a Java è la verbosità iniziale. Per stampare un semplice “Hello World” era necessario dichiarare una classe pubblica, un metodo statico e conoscere la firma di main.

Con la finalizzazione della JEP 512, Java introduce le classi dichiarate implicitamente e i metodi main di istanza. Ora è possibile scrivere programmi completi ed eseguibili con una sintassi ridotta all’osso, ideale sia per i principianti che per script rapidi:

// Questo è un file sorgente Java valido in JDK 25!
void main() {
    System.out.println("Benvenuti nel mondo super semplice di Java 25!");
}

La JVM si occupa di racchiudere implicitamente questo codice in una classe anonima a runtime, rimuovendo la necessità di dichiarazioni ridondanti.


2. Più Flessibilità nei Costruttori: Flexible Constructor Bodies (JEP 513)

Nelle versioni precedenti di Java, la chiamata al costruttore della superclasse (super(...)) o ad un altro costruttore della stessa classe (this(...)) doveva essere tassativamente la prima istruzione del costruttore.

Con la JEP 513, questa restrizione viene definitivamente eliminata. Gli sviluppatori possono ora eseguire calcoli preliminari, validare argomenti o preparare dati prima di richiamare il costruttore principale, a patto che tali istruzioni non accedano all’istanza in fase di creazione (this).

public class SottoClasse extends SuperClasse {
    public SottoClasse(int valore) {
        // Calcoli preliminari e validazioni prima di super()!
        int valoreValidato = valida(valore);
        super(valoreValidato);
    }

    private static int valida(int v) {
        if (v < 0) throw new IllegalArgumentException("Il valore deve essere positivo");
        return v;
    }
}

Questo rende i costruttori molto più espressivi e previene la necessità di ricorrere a costosi metodi factory statici per la sola validazione preventiva.


3. Prestazioni ed Efficienza di Memoria: Compact Object Headers (JEP 519)

Una delle novità più entusiasmanti sotto il cofano è la riduzione dell’overhead di memoria grazie ai Compact Object Headers.

Nelle architetture a 64 bit tradizionali, ogni oggetto Java porta con sé un’intestazione (header) che consuma da 96 a 128 bit di memoria per memorizzare metadati del GC, informazioni di blocco e l’identità della classe. La JEP 519 riduce questa intestazione a soli 64 bit.

I benefici di questo cambiamento sono eccezionali:

  • Risparmio Heap: Riduzione del consumo complessivo di memoria heap compreso tra il 10% e il 20% per la maggior parte delle applicazioni.
  • Miglioramento della Cache: Più oggetti possono essere memorizzati nella cache della CPU (data locality), migliorando le prestazioni generali senza modificare una singola riga di codice.

4. Condivisione dei Dati Semplificata: Scoped Values (JEP 506)

In concomitanza con la diffusione dei Virtual Threads (introdotti in Java 21), l’uso di ThreadLocal è diventato meno efficiente e rischioso a causa del potenziale overhead di memoria quando si gestiscono milioni di thread.

JDK 25 finalizza gli Scoped Values (JEP 506). Essi offrono una soluzione moderna, sicura ed estremamente efficiente per condividere dati immutabili all’interno di un thread e tra thread figlio.

private final static ScopedValue<User> CURRENT_USER = ScopedValue.newInstance();

void processRequest(Request req) {
    User user = authenticate(req);
    // Associa il valore all'interno di questo scope d'esecuzione
    ScopedValue.where(CURRENT_USER, user).run(() -> {
        serveRequest();
    });
}

void serveRequest() {
    // Accesso sicuro e ad altissime prestazioni al valore dello scope
    User user = CURRENT_USER.get();
    System.out.println("Processing for user: " + user.name());
}

5. Garbage Collection ultra-efficiente: Generational Shenandoah (JEP 521)

Il Garbage Collector Shenandoah (noto per i suoi tempi di pausa estremamente ridotti e costanti, indipendentemente dalla dimensione dell’heap) raggiunge la sua massima maturità in Java 25.

La JEP 521 stabilizza la modalità generazionale del Garbage Collector. Dividendo l’heap in generazioni giovani (young) e vecchie (old), Generational Shenandoah ottimizza la raccolta dei dati a ciclo di vita breve riducendo drasticamente il carico della CPU e migliorando il throughput delle applicazioni web e dei microservizi ad alto traffico.


Conclusioni

JDK 25 si dimostra un rilascio LTS solido e maturo. Non solo rende Java più accessibile e moderno da scrivere, ma introduce ottimizzazioni infrastrutturali che aumentano l’efficienza delle applicazioni a livelli mai visti prima.

Se state ancora utilizzando Java 17 o Java 21, JDK 25 offre una serie di motivi straordinari per pianificare una migrazione e godere da subito di migliori performance, minor consumo di memoria e una sintassi pulita ed espressiva.