Dopo sei mesi di sviluppo, Oracle ha pubblicato la piattaforma Java SE 24 (Java Platform, Standard Edition 24), la cui implementazione di riferimento è basata sul progetto open source OpenJDK. A parte l'eliminazione di alcune funzionalità obsolete, Java SE 24 mantiene la compatibilità con le versioni precedenti, così la maggior parte dei progetti Java esistenti funzionerà senza modifiche sulla nuova versione. Sono disponibili build pronte per l'installazione di Java SE 24 (JDK, JRE e Server JRE) per Linux (x86_64, AArch64), Windows (x86_64) e macOS (x86_64, AArch64). L'implementazione di riferimento di Java SE 24 sviluppata nell'ambito del progetto OpenJDK è completamente aperta sotto licenza GPLv2 con eccezioni GNU ClassPath che consentono il collegamento dinamico a prodotti commerciali.
Java SE 24 è classificato come una release con un ciclo di vita di supporto standard, con aggiornamenti rilasciati fino alla prossima versione. Per una release a lungo termine (LTS), si consiglia di utilizzare Java SE 21 o Java SE 17, con aggiornamenti previsti fino al 2031 e 2029, rispettivamente (pubblici fino al 2028 e 2026). Il supporto esteso per la release LTS di Java SE 8 durerà fino al 2030, mentre per Java SE 11 fino al 2032. La prossima release LTS sarà il rilascio autunnale di Java SE 25.
Tra le novità introdotte in Java SE 24:
- È stato introdotto un nuovo modo sperimentale di operare del garbage collector Shenandoah, in cui gli oggetti vengono trattati separatamente a seconda che siano vecchi o di recente creazione, al fine di migliorare l'efficienza nella pulizia degli oggetti con un breve tempo di vita. Questa nuova modalità offre una capacità di elaborazione più prevedibile, una maggiore resilienza alle variazioni del carico e una riduzione dell'uso della memoria durante la raccolta dei rifiuti. Lo scheduler Shenandoah mira a ridurre i tempi di fermo durante la raccolta dei rifiuti eseguendo una maggiore quantità di lavoro in parallelo con l'esecuzione delle applicazioni Java.
- È stata implementata nel JVM HotSpot un supporto sperimentale per intestazioni compatte degli oggetti, che su sistemi a 64 bit sono state ridotte da 96 a 64 bit (da 12 a 8 byte). La riduzione delle dimensioni delle intestazioni consente di ottimizzare la dimensione dell'heap e aumentare l'efficienza della cache.
- Nel garbage collector G1 è stata semplificata l'implementazione dei barrier che monitorano l'accesso della applicazione alla memoria. Nella nuova versione, le operazioni di estensione dei barrier sono state spostate a una fase più avanzata della compilazione nel C2 JIT. I test effettuati mostrano che questo spostamento consente di ridurre le spese generali nel compilatore JIT C2 del 10-20% a seconda dell'applicazione.
- È stato aggiunto un API per utilizzare le funzioni crittografiche di derivazione delle chiavi (KDF, key derivation function) che consentono di generare chiavi aggiuntive di lunghezza necessaria basate su una chiave segreta (ad esempio, una password) e un insieme di dati arbitrari. L'API KDF ha attualmente lo stato di anteprima (preview).
- È stata aggiunta la possibilità di caricamento e incorporamento delle classi in modo anticipato (Ahead-of-Time). Questa modifica permette di accelerare l'avvio di HotSpot JVM fornendo le classi utilizzate nell'applicazione già in uno stato caricato e assemblato. Durante il primo avvio dell'applicazione, lo stato di tutte le classi viene memorizzato nella cache e utilizzato per velocizzare il caricamento nei successivi avvii.
- È stata aggiunta la API Class-File per l'analisi, la generazione e la trasformazione dei file delle classi Java.
ClassFile cf = ClassFile.of(); ClassModel classModel = cf.parse(bytes); byte[] newBytes = cf.build(classModel.thisClass().asSymbol(), classBuilder -> { for (ClassElement ce : classModel) { if (!(ce instanceof MethodModel mm && mm.methodName().stringValue().startsWith("debug"))) { classBuilder.with(ce); } } });
- È stato aggiunto un API Stream avanzato, che supporta la definizione di operazioni intermedie personalizzate, utili nei casi in cui le operazioni intermedie integrate non siano sufficienti per la trasformazione dei dati desiderata. I gestori personalizzati vengono collegati tramite la nuova operazione intermedia Stream::gather(Gatherer), che elabora gli elementi del flusso applicando un gestore definito dall'utente. jshell> Stream.of(1,2,3,4,5,6,7,8,9).gather(new WindowFixed(3)).toList() $1 ==>> [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
- È stata proposta la quarta implementazione preliminare dei Valori Scoped, che consentono la condivisione di dati immutabili nei flussi e uno scambio efficiente di informazioni tra i sottoprodotti (i valori sono ereditati). I Valori Scoped si sviluppano per sostituire il meccanismo delle variabili locali per flusso e sono più efficienti quando si utilizzano un numero molto elevato di flussi virtuali (migliaia e milioni di flussi). La principale differenza tra i Valori Scoped e le variabili locali per flusso è che i primi vengono scritti una sola volta, non possono essere modificati successivamente e rimangono accessibili solo durante l'esecuzione del flusso.
- Nel meccanismo di corrispondenza dei modelli è stata aggiunta la supporto preliminare per 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 -> «ok»; case 1 -> «avviso»; case 2 -> «errore»; case int i -> «stato sconosciuto: » + i; } if (i instanceof byte b) { … b … }
- È stata proposta la nona implementazione preliminare dell'API Vector, che fornisce funzionalità per i calcoli vettoriali eseguiti utilizzando le istruzioni vettoriali dei processori x86_64 e AArch64, consentendo di applicare simultaneamente operazioni a più valori (SIMD). Diversamente dalle funzionalità di autovettorizzazione delle operazioni scalari fornite dal compilatore JIT HotSpot, la nuova API offre la possibilità di gestire esplicitamente la vettorizzazione per l'elaborazione parallela dei dati.
- È stata implementata la supporto per la sincronizzazione dei flussi virtuali senza il loro attacco (pinning) ai flussi della piattaforma. I flussi virtuali in un metodo o espressione sincronizzati in stato di blocco ora liberano il loro flusso della piattaforma, consentendo ad altri flussi virtuali di utilizzarlo, aumentando notevolmente il numero di flussi virtuali disponibili e migliorando la scalabilità delle applicazioni che utilizzano il multithreading.
- È stata aggiunta una terza variante preliminare della funzionalità che consente di specificare espressioni nei costruttori prima della chiamata a super(…), utilizzata per richiamare esplicitamente il costruttore della classe base dal costruttore della classe derivata, a condizione che queste espressioni non facciano riferimento all'istanza creata dal costruttore. class Outer { void hello() { System.out.println(«Ciao»); } class Inner { Inner() { hello(); super(); } } }
- Nell'utility jlink è stata implementata la supporto per la creazione di immagini run-time senza l'uso di file JMOD, consentendo di ridurre le dimensioni del JDK di circa il 25%.
- È stata aggiunta una seconda variante preliminare dell'uso di un'espressione «import module M» per importare immediatamente tutti i pacchetti esportati dal modulo specificato. Questa modifica semplifica notevolmente il riutilizzo delle librerie modulari, consentendo di collegare librerie e classi senza definire la loro posizione nella gerarchia dei pacchetti. Ad esempio, specificare «import module java.base» importerà tutti i 54 pacchetti del modulo java.base, che in precedenza avrebbero dovuto essere menzionati singolarmente («import java.io.*», «import java.util.*», ecc.).
- È stata aggiunta la quarta implementazione preliminare di classi implicitamente dichiarate e istanze senza nome del metodo «main», in cui è possibile farne a meno delle dichiarazioni public/static, del passaggio di un array di argomenti e di altre entità relative alla dichiarazione della classe. // prima public class HelloWorld { public static void main(String[] args) { System.out.println(«Ciao mondo!»); } } // ora è possibile void main() { System.out.println(«Ciao, Mondo!»); }
- È stata proposta per il test la quarta variante preliminare dell'API per la concorrenza strutturata (Structured Concurrency), che semplifica lo sviluppo di applicazioni multithread grazie alla gestione di più compiti eseguiti in diversi flussi come un unico blocco.
- Nell'API KeyPairGenerator, Signature e KeyFactory è stata aggiunta la supporto per gli algoritmi ML-KEM (CRYSTALS-Kyber) e ML-DSA (CRYSTALS-Dilithium), standardizzati dall'Istituto Nazionale degli Standard e della Tecnologia degli Stati Uniti (NIST) e resistenti agli attacchi su computer quantistici. Questi algoritmi utilizzano metodi crittografici basati sulla risoluzione di problemi di teoria delle reti, i cui tempi di risoluzione non differiscono tra computer classici e quantistici.
- Nell'aggregatore di spazzatura ZGC è stata rimossa la supporto per la modalità di lavoro non generativa, che non separa l'elaborazione degli oggetti «vecchi» e «giovani». A partire da Java SE 23, la modalità generativa ZGC è applicata di default.
- È stata aggiunta l'emissione di avvisi sull'uso delle API JNI (Java Native Interface) e FFM (Foreign Function & Memory) per preparare gli sviluppatori a limitazioni sull'accesso ai dati API a causa dell'introduzione in una delle future versioni della modalità di integrità, che per impostazione predefinita vieta l'interazione con il codice nativo.
- È stata attivata l'emissione di avvisi quando si utilizzano i metodi di accesso alla memoria esterna (al di fuori della JVM) forniti dalla classe sun.misc.Unsafe. Per l'accesso alla memoria al di fuori dell'heap e l'interazione con codice esterno è consigliato utilizzare l'API VarHandle. Nella versione precedente, il supporto per sun.misc.Unsafe è stato dichiarato obsoleto.
- È stato disabilitato il Security Manager, che da tempo non era più attuale e non è stato più richiesto dopo la cessazione del supporto per il plugin del browser. Il Security Manager è stato dichiarato obsoleto in Java 17. In una delle prossime versioni si prevede di rimuovere completamente il codice del Security Manager.
- È stato rimosso il codice per il supporto della piattaforma Windows a 32 bit sui sistemi x86. È stato dichiarato obsoleto e si prevede di rimuovere il port Java per i sistemi a 32 bit x86 (il supporto per Linux sui sistemi a 32 bit x86 sarà interrotto).
Si segnala inoltre la pubblicazione di un aggiornamento della piattaforma per la creazione di applicazioni con interfaccia grafica JavaFX 24 e una nuova versione della macchina virtuale universale GraalVM, che supporta l'esecuzione di applicazioni in JavaScript (Node.js), Python, Ruby, R, linguaggi per JVM (Java, Scala, Clojure, Kotlin) e linguaggi per i quali può essere generato bitcode LLVM (C, C++, Rust). Oltre al supporto per JDK 24, la nuova versione di GraalVM ha apportato ottimizzazioni per compiti legati all'apprendimento automatico, migliorato il supporto per la compilazione del bytecode Java in codice macchina, aggiunto il meccanismo SkipFlow per ridurre le dimensioni dei file eseguibili e ridurre i tempi di compilazione.
Fonte: opennet.ru
