Cosa c’è di nuovo in Java 17?

La versione Long-Term-Support (LTS) del linguaggio Java e della piattaforma runtime Java 17 è stata lanciata il 14 settembre 2021. Scopriamo le novità di Java 17 e se è necessario eseguire l’aggiornamento.

Molte applicazioni utilizzano versioni precedenti di Java, incluse le versioni LTS precedenti di Java: Java 11 e Java 8.

Perché le aziende dovrebbero eseguire l’aggiornamento alla versione Java più recente? L’aggiornamento a Giava 17 richiede impegno, principalmente per sfruttare al meglio le nuove caratteristiche e funzioni all’interno della JVM.

Molte aziende utilizzano le immagini Docker e Docker per passare facilmente a Java 17 con il minimo sforzo e tempo. Gli sviluppatori possono definire le loro pipeline di integrazione/distribuzione continua (CI/CD) ed eseguire tutto nelle immagini Docker. Ciò non influirà sugli altri team che utilizzano versioni Java precedenti, poiché possono utilizzare vecchie immagini Docker.

JAVA 17 Caratteristiche

Supporto per macOS e AArch64

Una delle funzionalità critiche di JVM aggiunte a questa versione è il miglioramento del supporto per macOS su architettura AArch64 utilizzando JEP 391. Supporterà l’ultima serie di processori (M1) Apple rilasciata con i propri computer nell’ultimo anno.

Non è necessariamente un grosso problema per gli utenti su quelle piattaforme poiché alcuni fornitori hanno lanciato versioni di JDK che supportano questa architettura e restituiscono persino il supporto da Java 8. Tuttavia, il sigillo di approvazione ufficiale è essenziale per garantire la manutenzione e il supporto futuri di la piattaforma. In confronto, il supporto per la piattaforma Linux/AArch64 è stato aggiunto a Java 9 e Windows/AArch64 in Java 16.

Classi sigillate

Sealed Classes è una funzionalità introdotta in Java 17. La funzionalità Sealed Classes ha terminato la sua fase di prova ed è diventata una piattaforma e un linguaggio ufficiali in Java 17. Consente a uno sviluppatore di specificare i sottotipi consentiti che un tipo può avere e impedire ad altri di estenderlo o implementarlo in un modo non previsto.

Le classi sigillate consentono inoltre al compilatore di generare errori in fase di compilazione quando si tenta di convertire un tipo non sigillato in un sottotipo non consentito. Java 17 offre anche una nuova pipeline di rendering per le app AWT/Swing che vengono eseguite su macOS utilizzando l’API Apple Metal invece di OpenGL. Ha un’API migliorata e funzionalità avanzate per generare numeri casuali.

Modifiche, eliminazioni e limitazioni in Java 17

Java 17 porta anche diverse modifiche, eliminazioni e nuove limitazioni.

Incapsulamento di interni JDK

Un cambiamento è la conclusione del processo di incapsulamento di JDK Internals. La prima volta che questo è stato introdotto era all’interno di Java 9 e dava avvisi durante il runtime quando un utente tentava di utilizzare la riflessione o simili per aggirare le consuete restrizioni sull’utilizzo delle API interne. Sono stati aggiunti anche argomenti della riga di comando per regolare questo comportamento.

Da Java 9 sono state create varie API per offrire un modo uniforme per svolgere le attività più comunemente utilizzate; gli utenti utilizzeranno queste API internamente. Con Java 16, l’impostazione predefinita è stata modificata da un avviso alla disabilitazione dell’accesso alla generazione di un’eccezione. Tuttavia, utilizza l’argomento della riga di comando per modificare il comportamento.

Con Java 17, l’argomento della riga di comando viene eliminato ed è possibile disattivare questa restrizione. Ciò significa che tutto l’accesso non autorizzato a tali API interne è ora protetto.

Semantica in virgola mobile sempre rigida

Un’ulteriore “rimozione” può essere descritta come la reintroduzione della semantica Always-Strict Floating Point. Java 1.2 ha introdotto modifiche alla semantica in virgola mobile predefinita in Java che consente alla JVM di scambiare una piccola quantità di precisione nei calcoli in virgola mobile per migliorare le prestazioni. Nelle classi e nei metodi in cui doveva essere utilizzata una semantica rigorosa, è stata aggiunta una parola chiave strictfp. Da allora, nelle CPU sono stati introdotti vari tipi di set di istruzioni, che consentono di utilizzare una semantica rigorosa in virgola mobile senza costi inutili. La necessità di implementare una semantica predefinita o rigorosa è stata eliminata.

Java 17 rimuove la semantica predefinita precedente e tutte le operazioni in virgola mobile vengono eseguite rigorosamente. Il termine strictfpis è ancora presente. Tuttavia, non ha alcun effetto e genera un avviso in fase di compilazione.

Compilazione anticipata (AOT).

Java 9 ha introdotto la compilazione anticipata (AOT) come funzionalità sperimentale che utilizza il compilatore Graal ed è stato scritto un codice JIT utilizzando Java. Java 10 ha reso il compilatore Graal utilizzabile come compilatore JIT in OpenJDK incorporando l’interfaccia JVMCI. Da quando è stato rilasciato, è stato un grande miglioramento. Il compilatore Graal ha visto enormi progressi e ha la sua JVM sotto il nome di GraalVM.

Attivazione RMI

L’attivazione RMI è stata eliminata in PEC 407 dopo la sua rimozione da Java 8 e infine deprecato e contrassegnato come requisito per la rimozione all’interno di Java 15. L’attivazione di RMI ha fornito un metodo per abilitare le risorse su richiesta degli oggetti distribuiti utilizzando RMI. Tuttavia, ha visto un utilizzo minimo e al momento è disponibile un’alternativa migliore. Il resto di RMI non è influenzato dall’eliminazione della parte di Attivazione.

Rimozione dell’API dell’applet

L’API dell’applet è stata finalmente designata per la rimozione da parte di PEC 398, inizialmente rimosso in Java 9. L’API dell’applet ha fornito un modo per integrare i controlli Java AWT/Swing in una pagina Web all’interno di un browser. Tuttavia, nessun browser moderno può supportarlo, il che significa che le applet sono state essenzialmente inaccessibili negli ultimi dieci anni circa.

Manager della sicurezza

La deprecazione più cruciale è che è il gestore della sicurezza ( PEC 411). Security Manager è in uso da un po’ di tempo da Java 1.0. È stato progettato per limitare ciò che Java può fare localmente sulla macchina, come limitare l’accesso a reti, file e altre risorse di rete. Cerca inoltre di eseguire il sandbox del codice non attendibile bloccando la riflessione e API specifiche.

La fine di Security Manager è iniziata in Java 12. È stato aggiunto un argomento della riga di comando per bloccare l’utilizzo di Security Manager in fase di esecuzione. La modifica apportata in Java 17 significa che verrà generato un avviso di runtime nella JVM quando si tenta di impostare un Security Manager, dalla riga di comando o dinamicamente in fase di esecuzione.

Funzionalità dell’incubatrice e dell’anteprima

Molti si sono chiesti se Java 17 avrebbe delle funzionalità di anteprima e incubatore, considerando che Java 17 è stato promosso come una versione supportata a lungo termine. Java 17 ha due moduli di incubazione e una funzione di anteprima!

API vettoriali

API vettoriale ( PEC 414) è attualmente nella sua seconda fase dell’incubatore. L’API consente agli sviluppatori di definire il calcolo vettoriale che il compilatore JIT convertirà quindi nell’istruzione vettoriale appropriata supportata dall’architettura della CPU su cui gira la JVM (ad esempio, utilizzando quelle dei set di istruzioni SSE o AVX).

In precedenza, gli sviluppatori dovevano utilizzare funzioni scalari o creare librerie native specifiche per la piattaforma. L’implementazione dell’API Vector in Java fornisce anche un meccanismo di fallback senza interruzioni che era complicato nelle versioni precedenti.

La standardizzazione dell’API Vector consente alle classi all’interno del JDK di utilizzarla. I metodi Java Arrays mismatch() possono essere modificati per essere eseguiti su Java, eliminando la necessità di mantenere e scrivere implementazioni specifiche per piattaforme multiple all’interno della JVM.

API di memoria e funzioni esterne

Un’ulteriore funzionalità dell’incubatrice è chiamata Foreign Function & Memory API ( PEC 412). È un’evoluzione e una fusione di altri due moduli di incubazione di Java 16 che è The Foreign Linker API ( PEC 389) e API di memoria esterna ( PEC 393). Entrambi forniscono l’accesso alla memoria e al codice nativi utilizzando la programmazione tipizzata staticamente scritta in Java.

Pattern Matching per Switch

La caratteristica finale dell’anteprima della lingua inclusa in Java 17 è l’inclusione di Pattern Matching per Switch ( PEC 406). Questa funzionalità del linguaggio espande le espressioni e le istruzioni switch in base al tipo, in modo simile alla sintassi utilizzata tramite Pattern Matching (PEC 394), che è diventato standard con Java 16.

In passato, se volevi eseguire azioni diverse in base alla natura dinamica di un oggetto, avresti dovuto costruire una catena if-else utilizzando un’istanza di controlli come:

String type(Object o) {
  if (o instanceof List) {
    return "A List of things.";
  }
  else if (o instanceof Map) {
    return "A Map! It has keys and values.";
  }
  else if (o instanceof String) {
    return "This is a string.";
  }
  else {
    return "This is something else.";
  }
}

Combinando l’espressione switch e la nuova funzione di corrispondenza dei modelli per switch, il processo può essere ridotto a qualcosa di simile a:

String type(Object o) {
  return switch (o) {
    case List l -> "A List of things.";
    case Map m -> "A Map! It has keys and values.";
    case String s -> "This is a string.";
    default -> "This is something else.";
  };
}

Come avrai notato, c’è la dichiarazione di una variabile in fase di verifica. Come le altre variabili in Pattern, la corrispondenza dell’istanza indica che questo oggetto è stato sottoposto a controllo del tipo e cast ed è disponibile dalla variabile all’interno della sua area corrente.

La funzione di anteprima è un altro passo verso il pattern matching. Il passaggio successivo consiste nell’includere la capacità di decostruire array e record.

Dovresti aggiornare a Java 17?

Sì, è necessario aggiornare costantemente alla versione più recente, tuttavia non appena il primo giorno. Il software e le librerie in uso potrebbero non essere stati aggiornati per includere la compatibilità con Java 17, quindi potrebbe essere necessario attendere un po’ di tempo prima che il processo sia terminato.

Se sei bloccato con una versione LTS di Java come Java 8 o Java 11, ci sono numerose opzioni all’interno della lingua e all’interno della JVM stessa che richiedono un aggiornamento fino a Java 17. Essendo una versione di manutenzione a lungo termine, c’è un’alta probabilità che il tuo ambiente di produzione venga eventualmente aggiornato anche a Java 17.

Se stai iniziando un progetto completamente nuovo o stai preparando il tuo progetto per Java 17, passare a Java 17 prima piuttosto che dopo è probabilmente la scelta più efficiente poiché riduce i costi di spostamento. Ciò consente inoltre agli sviluppatori che lavorano al progetto di utilizzare tutte le ultime funzionalità e il lato operativo.

Puoi sfruttare i numerosi miglioramenti che si sono verificati negli ultimi anni, come il supporto migliorato per i contenitori in esecuzione su Java, nonché le nuove implementazioni di Garbage Collector a bassa latenza.