Dopo sei mesi di sviluppo, Oracle ha pubblicato la piattaforma Java SE 25 (Java Platform, Standard Edition 24), della quale utilizza il progetto OpenJDK come implementazione di riferimento. Fatta eccezione per la rimozione di alcune funzionalità obsolete, Java SE 25 mantiene la compatibilità retroattiva con le versioni precedenti della piattaforma Java: la maggior parte dei progetti Java precedentemente scritti funzionerà senza modifiche con la nuova versione. Le build pronte per l'installazione di Java SE 25 (JDK, JRE e Server JRE) sono disponibili per Linux (x86_64, AArch64), Windows (x86_64) e macOS (x86_64, AArch64). L'implementazione di riferimento di Java SE 25, sviluppata nell'ambito del progetto OpenJDK, è completamente open source sotto la licenza GPLv2 con eccezioni GNU ClassPath, che consentono il collegamento dinamico a prodotti commerciali.
Java SE 25 è classificata tra le versioni con supporto a lungo termine, gli aggiornamenti per la quale saranno rilasciati fino al 2033 (gli aggiornamenti pubblici saranno disponibili fino a settembre 2030). Anche le versioni Java SE 17 e 21 continuano a essere supportate come versioni con supporto a lungo termine (LTS), con aggiornamenti previsti fino al 2029 e 2031, rispettivamente (aggiornamenti pubblici fino al 2026 e 2028). Il supporto esteso per le versioni LTS di Java SE 8 e 11 si protrarrà fino al 2030 e 2032.
Tra le novità proposte in Java SE 25 (1, 2, 3, 4):
- È stato aggiunto un API sperimentale StableValue per lavorare con oggetti che contengono dati immutabili e sono gestiti nella JVM come costanti. A questi oggetti vengono applicate ottimizzazioni delle prestazioni analoghe ai campi con la parola chiave "final". L'API StableValue separa la creazione di valori costanti dalla loro inizializzazione, garantendo che un valore possa essere inizializzato solo una volta, riducendo il tempo di avvio delle applicazioni e consentendo di applicare nel codice utente ottimizzazioni di folding delle costanti (constant-folding), precedentemente usate solo nel codice interno del JDK. class Application { // Era: // static final UserService USERS = new UserService(); // È diventato: // static final StableValue USERS = StableValue.of(); public static UserService users() { return USERS.orElseSet(UserService::new); } }
- È stato aggiunto un API sperimentale per la codifica e la decodifica di oggetti contenenti chiavi crittografiche, certificati e liste di certificati revocati, utilizzando il formato PEM (Pivacy-Enhanced Mail).
- È stata aggiunta la supporto ai Scoped Values, che consentono di condividere dati immutabili nei thread e di scambiare dati in modo efficiente tra i thread figlio (i valori vengono ereditati). Gli Scoped Values sono in fase di sviluppo per sostituire il meccanismo delle variabili locali al thread e sono più efficienti quando si utilizzano un numero molto elevato di thread virtuali (migliaia e milioni di thread). La principale differenza tra Scoped Values e le variabili locali al thread è che i primi vengono scritti una volta, non possono essere modificati ulteriormente e sono accessibili solo durante l'esecuzione del thread.
- È stata aggiunta un'API per l'uso di funzioni crittografiche per la derivazione delle chiavi (KDF, key derivation function), che consentono di generare chiavi aggiuntive della lunghezza necessaria a partire da una chiave segreta (ad esempio, una password) e da un insieme di dati arbitrari.
- È stato rimosso il codice e gli script di build per il supporto dei sistemi x86 a 32 bit. La cessazione del supporto per i sistemi x86 a 32 bit ha semplificato l'infrastruttura per la build e i test del JDK e ha reso possibile implementare funzionalità legate alle piattaforme senza creare gestori di fallback per i sistemi a 32 bit.
- È stata aggiunta la possibilità di utilizzare un'unica espressione «import module M» per importare tutti i pacchetti esportati dal modulo specificato. Questa modifica semplifica notevolmente il riutilizzo delle librerie modulari, consentendo di includere librerie e classi senza definire la loro posizione nella gerarchia dei pacchetti. Ad esempio, specificando «import module java.base» si importeranno tutti i 54 pacchetti che fanno parte del modulo java.base, che prima sarebbe stato necessario menzionare singolarmente («import java.io.*», «import java.util.*» e così via).
- È stata proposta una variante compatta per la scrittura di programmi, che potrebbe rivelarsi utile per l'insegnamento e nello sviluppo di piccole applicazioni. Nella forma compatta non è necessaria la definizione di classi superflue, vengono importati automaticamente API standard e sono disponibili metodi semplificati di input/output. Ad esempio, l'applicazione «Hello, World!» può essere ridotta a: void main() { IO.println(«Hello, World!»); }
- È consentito specificare nelle espressioni dei costruttori prima della chiamata a super(…), utilizzata per invocare esplicitamente il costruttore della classe padre dal costruttore della classe derivata, se queste espressioni non fanno riferimento all'istanza creata dal costruttore. class Outer { void hello() { System.out.println("Hello"); } class Inner { Inner() { hello(); super(); } } }
- È stata aggiunta la modalità generativa per il garbage collector Shenandoah, in cui gli oggetti vecchi e quelli appena creati vengono elaborati separatamente per migliorare l'efficienza della pulizia degli oggetti con breve vita. La nuova modalità garantisce una larghezza di banda più prevedibile, maggiore resilienza alle variazioni di carico e una riduzione dell'uso della memoria durante la raccolta dei rifiuti. Lo scheduler di Shenandoah è progettato per ridurre i tempi di arresto durante la raccolta dei rifiuti effettuando un maggior volume di lavoro in parallelo con l'esecuzione di applicazioni Java.
- È stata semplificata la creazione della cache per il caricamento e la composizione dei classi a priori (Ahead-of-Time), che consente di accelerare l'avvio della HotSpot JVM sfruttando classi già caricate e composte. Non è più necessario eseguire operazioni separate per registrare le attività e creare la cache, basta un solo comando: java -XX:AOTCacheOutput=app.aot -cp app.jar com.example.App …
- All'avvio della HotSpot Java VM è stata implementata la possibilità di utilizzare profili di esecuzione dei metodi ottenuti durante l'ultima esecuzione dell'applicazione. Questa modifica consente al compilatore JIT di fare a meno della raccolta di statistiche e di iniziare immediatamente a generare codice nativo senza attendere la formazione del profilo.
- Nella HotSpot JVM è stata implementata la supporto per intestazioni compatte degli oggetti, il cui size sui sistemi a 64 bit è stato ridotto da 96 a 64 bit (da 12 a 8 byte). La riduzione delle dimensioni delle intestazioni permette di ridurre la dimensione dell'heap e di migliorare l'efficienza del cache.
- È stata proposta un'implementazione di prova dell'API Vector, che offre funzioni per calcoli vettoriali eseguiti utilizzando le istruzioni vettoriali dei processori x86_64 e AArch64, consentendo di applicare contemporaneamente operazioni a più valori (SIMD). A differenza delle capacità di auto-vettorizzazione delle operazioni scalari fornite dal compilatore JIT HotSpot, la nuova API consente un controllo esplicito sulla vettorizzazione per l'elaborazione parallela dei dati.
- È stato proposto per la sperimentazione un quinto preliminare dell'API per la concorrenza strutturata (Structured Concurrency), che semplifica lo sviluppo di applicazioni multi-thread gestendo più attività eseguite in thread diversi come un'unica unità.
- Nel meccanismo di corrispondenza dei modelli, è stata proposta una terza versione preliminare che consente l'uso di tipi primitivi (int, byte, char e altri tipi di base che non sono oggetti) in tutti i tipi di modelli, nell'operatore 'instanceof' e nei blocchi 'switch'. switch (x.getStatus()) { case 0 -> 'okay'; case 1 -> 'warning'; case 2 -> 'error'; case int i -> 'unknown status: ' + i; } if (i instanceof byte b) { … b … }
- Nel JDK Flight Recorder (JFR) è stata aggiunta la supporto sperimentale per il profiling con tracciamento più preciso dell'uso delle risorse CPU sulla piattaforma Linux. Le informazioni sui tempi di esecuzione delle varie costruzioni possono essere visualizzate graficamente utilizzando diagrammi colorati 'FlameGraph'.
- È stata migliorata la stabilità del JDK Flight Recorder (JFR) durante il campionamento asincrono degli stack dei thread Java, evitando il traversamento dello stack delle chiamate solo nei 'safepoints'.
- Nel JDK Flight Recorder (JFR) sono stati aggiunti strumenti di tracciamento e valutazione del tempo di esecuzione dei metodi. È supportato il tracciamento dello stack delle chiamate di specifici metodi e la registrazione di statistiche dettagliate sulle chiamate ai metodi, che includono metriche come il tempo di esecuzione e il numero di chiamate.
Fonte: opennet.ru
