JavaRush /Java Blog /Random-IT /Java 14: cosa c'è di nuovo?

Java 14: cosa c'è di nuovo?

Pubblicato nel gruppo Random-IT
I problemi del mondo sono i problemi del mondo e il nuovo Java è nei tempi previsti. Cioè, esattamente una volta ogni sei mesi. La versione finale di Java 14 è stata rilasciata il 17 marzo e ha introdotto diverse interessanti novità nel linguaggio rivolte agli sviluppatori. Java 14: cosa c'è di nuovo?  -1Tra questi ci sono il supporto sperimentale per la parola chiave record , il supporto per la corrispondenza dei modelli nell'operatore " istanza di ", NullPointerExceptions più user-friendly, l'"anteprima" ampliata dei blocchi di testo , un'opzione predefinita aggiornata e molto altro. Ricordiamo che tutte le innovazioni in Java iniziano con proposte di estensione ( JEP, Java Enhancement Proposals ). Gli sviluppatori propongono modifiche, queste vengono riviste dai genitori Java "ufficiali" e quindi alcune di queste modifiche vengono accettate, dopodiché diventano parte del JDK. E ora - tutto in ordine.

JEP 359: Documenti

I record, conosciuti anche come Records, sono disponibili per JDK 14 in modalità anteprima, e questo è qualcosa di completamente nuovo per Java. In effetti, abbiamo davanti a noi un nuovo tipo sviluppato durante il progetto Valhalla . I record sono simili alle enumerazioni e consentono di semplificare il codice. Essenzialmente, sostituiscono le classi che hanno uno stato ma nessun comportamento. In poche parole, ci sono campi, nessun metodo. Nel caso delle classi, a volte dobbiamo scrivere molto codice ripetitivo che non sempre è necessario: costruttori, funzioni di accesso, equals(), hashCode(), toString(), ecc. Per evitare questo codice ripetitivo, Java prevede per utilizzare la registrazione. Ecco la versione classica:
final class Triangle {
 	public final int x;
public final int y;
public final int z;

    public Triangle(int x, int y, int z) {
         this.x = x;
         this.y = y;
    this.z = z;
    }
    // equals, hashCode, toString
Passiamo a Java 14 e utilizziamo record:
public record Triangle(int x, int y, int z){}
È tutto. Tieni presente che le registrazioni attualmente esistono in forma di anteprima, quindi per provarle nella pratica devi scaricare jdk14 e inserire il comando:
javac —enable-preview —release 14 Triangle.java
I record sono classi, anche se con limitazioni. Non possono estendere altre classi o dichiarare campi (ad eccezione dei finali privati ​​che corrispondono ai componenti della dichiarazione di stato). Le registrazioni sono implicitamente definitive e non possono essere astratte. I record differiscono dalle classi normali in quanto non possono separare la loro API dalla sua rappresentazione. Ma la perdita di libertà è compensata da una maggiore precisione. Anche i componenti del record sono implicitamente definitivi.

JEP 305: Pattern Matching per istanza di (Anteprima)

La funzionalità Pattern Matching , introdotta in Java 14 in anteprima, è pensata per combinare il controllo del tipo di un oggetto e la sua conversione nell'operatore istanzaof . In altre parole, prima di Java 14 ci sarebbe stato, ad esempio, il seguente codice:
Object object = Violin;

if (object instanceof Instrument) {
    Instrument instrument = (Instrument) object;
    System.out.println(instrument.getMaster());
}
Come puoi vedere, dobbiamo trasmettere l'oggetto alla classe di cui vogliamo utilizzare i metodi. Ora Java 14 e la funzione Pattern Matching connessa ti consentono di ridurre il codice a quanto segue:
Object object = Violin;

if (object instanceof Instrument instrument){
    System.out.println(instrument.getMaster());
}

JEP 343: Strumento di imballaggio (incubatore)

JDK 8 aveva uno strumento Javapackager progettato per JavaFX. Tuttavia, in seguito alla separazione di JavaFX da Java con il rilascio di JDK 11, il popolare javapackager non era più disponibile. Javapackager era uno strumento di confezionamento. Permetteva di impacchettare le applicazioni Java in modo tale da poter essere installate come tutti gli altri programmi “normali”. Ad esempio, crea file exe per utenti Windows e avvia un'applicazione Java come un essere umano, con un doppio clic. Naturalmente, uno strumento del genere è gravemente carente, quindi JEP 343 ha introdotto un nuovo strumento, jpackage , che impacchetta un'applicazione Java in un pacchetto specifico della piattaforma contenente tutte le dipendenze necessarie. Formati di pacchetto supportati per una piattaforma specifica:
  • Linux: deb e giri/min
  • macOS: pkg e dmg
  • Windows: MSI ed EXE

JEP 345: allocazione della memoria compatibile con NUMA per G1

JEP 345 serve esclusivamente per implementare il supporto NUMA (Non-uniform memory access). Si tratta di architetture di accesso alla memoria eterogenee, un modo di impostare un cluster di microprocessori in un sistema multiprocessore in cui la memoria può essere distribuita localmente: ciascun core del processore riceve una piccola quantità di memoria locale, mentre gli altri core hanno accesso ad essa. Il JEP 345 prevede di dotare il garbage collector G1 della capacità di sfruttare tali architetture. Tra le altre cose, questo approccio aiuta a migliorare le prestazioni su macchine molto potenti.

JEP 349: streaming di eventi JFR

Java Flight Recorder (JFR) fa ora parte di OpenJDK ed è quindi disponibile gratuitamente. JDK 14 aggiunge un'API per il tracciamento al volo degli eventi JFR (JDK Flight Recorder), in particolare per organizzare il monitoraggio continuo delle applicazioni attive e inattive. Si registrano gli stessi eventi dell'opzione non streaming, con un sovraccarico inferiore all'1%. In questo modo gli eventi verranno trasmessi in streaming contemporaneamente all'opzione non streaming. Tuttavia, JEP 349 non deve consentire richiamate sincrone per il consumatore corrispondente. Anche i dati dei record archiviati nella memoria intermedia non dovrebbero essere accessibili. Tecnicamente, il pacchetto jdk.jfr.consumer nel modulo jdk.jfr verrà esteso con funzionalità per l'accesso asincrono agli eventi.

JEP 352: buffer di byte mappati non volatili

Come sappiamo, Java NIO (New IO) File API esiste da JDK 1.4 e quindi è stato introdotto un nuovo miglioramento chiamato Path. Path è un'interfaccia che sostituisce la classe java.io.File come rappresentazione di un file o di una directory quando lavoriamo in Java NIO. JEP 352 estende MappedByteBuffer per caricare una parte dei dati del file nella memoria non volatile (NVM). Questa memoria del computer, in cui i dati non andranno persi anche se si spegne il computer (spesso chiamata memoria persistente), viene utilizzata per archiviare i dati in modo permanente. Questa proposta di miglioramento Java fornisce un nuovo modulo e una nuova classe per l'API JDK: il modulo jdk.nio.mapmode, che offre nuove modalità (READ_ONLY_SYNC, WRITE_ONLY_SYNC) per la creazione di buffer di byte mappati (MappedByteBuffer) che fanno riferimento a NVM.

JEP 358: utili NullPointerException

NullPointerExceptions sarà ora più facile da usare per i programmatori. Nel senso che la descrizione dell'eccezione sarà molto più informativa di prima. Questo perché alla JVM è stato insegnato ad analizzare in modo più accurato le istruzioni del bytecode del programma e può indicare quale variabile porta a un valore zero. Diciamo che abbiamo il codice:
a.getMessage().getUserInfo().getName()
In qualsiasi Java più recente otterremo il solito registro degli errori, che non risponde alla domanda su chi sia esattamente nullo:
Exception in thread "main" java.lang.NullPointerException
	at Main.main(Main.java:12)
Ed ecco cosa ti darà Java 14 se decidi di provare questa funzionalità di anteprima:
Exception in thread "main" java.lang.NullPointerException: Cannot invoke "UserInfo().getName()" because the return value of "Message().getUserInfo()" is null
	at Main.main(Main.java:12)
Questa catena è molto più comprensibile e consente di affrontare l'errore molto più velocemente.

JEP 361: Cambia espressione (standard)

L'operatore Switch aggiornato era disponibile nelle versioni Java 12 e 13 precedenti, ma solo come funzionalità di anteprima, ovvero non era abilitato per impostazione predefinita. Ora in JDK 14 tutto funziona immediatamente. Java 14 introduce una nuova forma semplificata del blocco switch con etichette case L -> .... La nuova forma semplifica il codice in alcuni casi. Qui ci sono un paio di esempi. Diciamo di avere un'enumerazione che descrive i giorni della settimana. Possiamo scrivere codice classico (pre-Java 14):
switch (day) {
    case MONDAY:
    case FRIDAY:
    case SUNDAY:
        System.out.println(6);
        break;
    case TUESDAY:
        System.out.println(7);
        break;
    case THURSDAY:
    case SATURDAY:
        System.out.println(8);
        break;
    case WEDNESDAY:
        System.out.println(9);
        break;
}
Ed ecco un'opzione che utilizza Java 14:
switch (day) {
    case MONDAY, FRIDAY, SUNDAY -> System.out.println(6);
    case TUESDAY                -> System.out.println(7);
    case THURSDAY, SATURDAY     -> System.out.println(8);
    case WEDNESDAY              -> System.out.println(9);
}
Puoi anche scrivere blocchi su più righe e restituire un valore con la nuova parola chiave yield:
int result = switch (s) {
    case "Working from Home" -> 1;
    case "Working from Office" -> 2;
    default    -> {
        System.out.println("Neither Home nor Office… Cafe? Car? Park?...");
        yield 0;
    }
};
Ci sono alcune cose più importanti da tenere a mente quando si utilizzano i nuovi switch . In particolare è necessario ricordare che le opzioni devono essere esaustive. Cioè, per tutti i valori possibili deve esserci un'etichetta di commutazione corrispondente. Poiché yield è ora una parola chiave, in Java 14 è possibile creare una classe chiamata yield. In generale, se vuoi imparare come utilizzare gli switch aggiornati, vai a JEP 361 e studia. Ci sono molte informazioni interessanti lì.

JEP 362: deprecate le porte Solaris e SPARC

È improbabile che molti dei nostri lettori ricordino il sistema operativo Solaris . Questo sistema operativo basato su UNIX, creato dai genitori di Java, Sun Microsystems, veniva utilizzato principalmente per server sull'architettura SPARC... Troppe parole sconosciute per centimetro quadrato? Niente di grave: JEP 362 termina il supporto per le piattaforme Solaris/SPARC, Solaris/x64 e Linux/SPARC. Cioè, i loro port sono ora deprecati e in futuro molto probabilmente verranno rimossi da OpenJDK. Tuttavia, le versioni precedenti di Java (precedenti a JDK 14) relative alle porte Solaris/SPARC, Solaris/x64 e Linux/SPARC dovrebbero funzionare senza modifiche. Se sei un appassionato di storia e sei interessato alle tecnologie di un passato non così lontano, vai su Wikipedia e leggi l' architettura SPARС .

JEP 363: rimuovere il Garbage Collector Concurrent Mark Sweep (CMS).

Il garbage collector CMS (Concurrent Mark Sweep) è destinato alla rimozione perché due anni fa è stato contrassegnato come obsoleto e non mantenuto. Tuttavia, gli utenti di versioni precedenti di Java che utilizzano CMS GC possono espirare: lo scopo di questo JEP non è rimuovere il builder dalle versioni precedenti di JDK. Inoltre, la combinazione degli algoritmi di garbage collection ParallelScavenge e SerialOld (in esecuzione con le opzioni "-XX:+UseParallelGC -XX:-UseParallelOldGC") è stata deprecata.

JEP 364: ZGC su macOS e JEP 365: ZGC su Windows

Esiste un interessante garbage collector chiamato Z Garbage Collector (ZGC) . Funziona in modalità passiva e cerca di ridurre al minimo i ritardi dovuti alla garbage collection: il tempo di arresto quando si utilizza ZGC non supera i 10 ms. Può funzionare con heap piccoli e giganti (quelli che occupano molti terabyte). JEP 364 e JEP 365 sono praticamente gemelli. JEP 364 porta Z Garbage Collector su MacOS. Parte del JEP descrive anche la funzionalità del raccoglitore per liberare la memoria inutilizzata del dispositivo, come specificato in JEP 351 , questo avviene a partire da Java 13. L'implementazione ZGC su macOS ha due parti:
  • Supporto di memoria multi-mappatura su macOS
  • Supporto ZGC per la prenotazione continua della memoria
JEP 365 fornisce il supporto per ZGC già su Windows e anche in modalità sperimentale. È il seguente:
  • Supporto di memoria multi-mappatura
  • Supporto per la mappatura della memoria basata sul file di paging in uno spazio di indirizzi riservato
  • Supporto per la mappatura e l'annullamento della mappatura di parti arbitrarie dell'heap
  • Supporto per il commit e il non commit di parti arbitrarie dell'heap

JEP 366: deprecata la combinazione ParallelScavenge + SerialOld GC

Questo JEP depreca la combinazione degli algoritmi di garbage collection Parallel Scavenge e Serial Old. Questa combinazione doveva essere abilitata manualmente utilizzando i parametri della riga di comando -XX: + UseParallelGC -XX: -UseParallelOldGC. Gli autori ritengono che la combinazione sia molto specifica, ma richieda anche un notevole sforzo di manutenzione. Quindi ora l'opzione -XX: UseParallelOldGC è deprecata e verrà visualizzato un avviso se utilizzata.

JEP 367: rimuovere gli strumenti e l'API Pack200

Pack200 è un formato di archivio ottimizzato per la memorizzazione di file di classi Java compilati. Questo strumento è stato contrassegnato come deprecato a partire da Java 11. Ora è stata ufficialmente annunciata la rimozione degli strumenti API pack200, unpack200 e Pack200 dal pacchetto java.util.jar . Questa tecnologia è stata introdotta in Java 5 come mezzo per gestire una larghezza di banda molto limitata (modem, è spaventoso dirlo e ricordarlo, 56k) e uno spazio di archiviazione insufficiente sui dischi rigidi. Qualche tempo fa, Java 9 ha introdotto nuovi schemi di compressione. Gli sviluppatori sono incoraggiati a utilizzare jlink .

JEP 368: Blocchi di testo (seconda anteprima)

I blocchi di testo sono apparsi per la prima volta in Java 13. Sono stringhe letterali multilinea che evitano la necessità della maggior parte delle sequenze di escape, formattano automaticamente la stringa e consentono inoltre allo sviluppatore di formattare la stringa se necessario. Questa utile funzionalità è ora disponibile in Java 14 (2a anteprima). Lo scopo principale dei blocchi di testo è migliorare la gestione dei valori letterali multilinea confusi. Ciò semplifica notevolmente la lettura e la scrittura di query SQL, codice HTML e XML e JSON. Esempio HTML senza blocchi di testo:
String html = "<html>\n" +
              "    <body>\n" +
              "        <p>Hello, JavaRush Student</p>\n" +
              "    </body>\n" +
              "</html>\n";
Come rappresentare lo stesso con blocchi di testo:
String html = """
              <html>
                  <body>
                      <p>Hello, JavaRush Student</p>
                  </body>
              </html>
              """;
Il delimitatore di apertura è una sequenza di tre virgolette doppie ("" "), seguite da zero o più spazi e quindi da un delimitatore di riga. Il contenuto inizia dal primo carattere dopo il delimitatore di riga del delimitatore di apertura. Il delimitatore di chiusura è è stata scelta una sequenza di tre virgolette doppie " _ ) in modo che i caratteri potessero essere visualizzati senza escape e distinguere visivamente un blocco di testo da una stringa letterale. All'inizio del 2019, JEP 355 ha proposto blocchi di testo come continuazione di JEP 326 (Raw String letterali), ma sono stati ritirati. Nello stesso anno, JDK 13 ha introdotto la funzionalità di anteprima dei blocchi di testo e ora Java 14 ha aggiunto due nuove sequenze di escape. Questo è un terminatore di riga, indicato con \, e il secondo è per uno spazio singolo, indicato con /s. Un esempio di utilizzo dei ritorni a capo senza blocchi di testo:
String literal = "This is major Tom to Ground Control " +
"I am stepping through the door... " +
"Wait… What???";
E ora con la sequenza di escape \<line-terminator>:
String text = """
                This is major Tom to Ground Control \
                I am stepping through the door... \
                WaitWhat???\
                """;
La sequenza di escape \s viene utilizzata per tenere conto degli spazi bianchi finali, che vengono ignorati dal compilatore per impostazione predefinita. Conserva tutti gli spazi bianchi che lo precedono. Esempio:
String text1 = """
               line1
               line2 \s
               line3
               """;

String text2 = "line1\nline2 \nline3\n";
text1e text2sono identici.

JEP 370: API di accesso alla memoria esterna (incubatore)

Molte librerie e programmi Java popolari hanno accesso alla memoria esterna. Ad esempio, API Ignite, MapDB, Memcached e Netty ByteBuf. In tal modo, possono evitare i costi e l'imprevedibilità associati alla garbage collection (specialmente quando si servono cache di grandi dimensioni), condividere la memoria tra più processi e serializzare e deserializzare il contenuto della memoria mappando i file in memoria (ad esempio, utilizzando mmap). Tuttavia l'API Java non dispone ancora di una soluzione adeguata per l'accesso alla memoria esterna. JDK 14 include un'anteprima dell'API Foreign-Memory Access , che consente alle applicazioni Java di accedere in modo sicuro ed efficiente alle regioni di memoria esterne all'heap JVM utilizzando le nuove astrazioni MemorySegment, MemoryAddress e MemoryLayout.

conclusioni

Allora, cosa ne pensate? Rispetto a Java 13, il nuovo Java 14 offre molti altri miglioramenti importanti in diversi settori. Molto probabilmente, la cosa più importante per gli sviluppatori sarà lo switch aggiornato, le eccezioni estese NullPointerExceptions e i record. Oppure no?.. Non dimenticare di provare le nuove funzionalità di Java 14, è molto utile anche per i principianti. Buona fortuna con i tuoi studi!
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION