JavaRush /Java Blog /Random-IT /Rilasciato Java 11: nuove funzionalità e funzionalità

Rilasciato Java 11: nuove funzionalità e funzionalità

Pubblicato nel gruppo Random-IT
In precedenza, le nuove versioni di Java apparivano raramente e con ritardi. Ora Oracle mantiene con successo il ritmo che si è prefissato di “nuovo Java ogni sei mesi”. Così qualche giorno fa, rigorosamente nei tempi previsti, abbiamo finalmente ricevuto Java SE 11 e l'implementazione del JDK (Java Development Kit). Rilasciato Java 11: nuove funzionalità e funzionalità - 1Come sempre, la nuova versione sarà compatibile con quelle vecchie e il supporto per Java 11 terminerà non prima di dicembre 2026.

Nuove funzionalità in Java SE 11 (visibili agli sviluppatori)

Ricordiamo che in Java le modifiche vengono apportate attraverso l'implementazione del PEC “JDK Enhancement Proposal”. JEP è una proposta per migliorare OpenJDK e può essere approvata, ritardata o rifiutata. Cioè, in sostanza, una raccolta di PEC è una strategia di sviluppo per OpenJDK. Tra parentesi quadre prima della nuova “funzione” indicheremo il numero del PEC corrispondente. [323] Sintassi della variabile locale per i parametri lambda - sintassi var per i parametri lambda Java 10 ha introdotto la parola chiave var, che ha reso possibile non specificare esplicitamente il tipo di una variabile locale. Ciò ha semplificato il codice. JEP 323 espande l'uso di questa sintassi con espressioni lambda. Esempio semplice:
list.stream ()
                 .map ((var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
Come scrive Simon Ritter , un noto evangelista Java, un programmatore Java esperto noterà che l'uso di var in questo caso potrebbe non essere necessario, poiché il codice sopra può essere sostituito con il seguente:
list.stream ()
                  .map (s -> s.toLowerCase ())
                  .collect (Collectors.toList ());
Perché, allora, supportare var? C'è solo un caso speciale: quando vuoi aggiungere un'annotazione a un parametro lambda. Ciò non può essere fatto senza il coinvolgimento di qualche tipo e, per evitare di dover utilizzare un tipo esplicito, possiamo semplificare il tutto utilizzando var in questo modo:
list.stream ()
                 .map ((@ Notnull var s) -> s.toLowerCase ())
                 .collect (Collectors.toList ());
[330] Avvio di programmi con codice sorgente a file singolo Miglioramento del launcher Java per avviare un programma come un singolo file con codice sorgente Java Java viene spesso criticato per la sua sintassi dettagliata e la "cerimonia" in più passaggi che prevede il lancio anche di un'applicazione banale. A volte questo spaventa i neofiti. Per scrivere un'applicazione che stampi semplicemente " Hello World! " ", è necessario scrivere una classe con un voidmetodo main statico pubblico e utilizzare il metodo System.out.println. Fatto ciò è necessario compilare il codice utilizzando javac . Infine, è possibile avviare l'applicazione, che visualizzerà lo sfortunato saluto (ovviamente, l'ambiente di sviluppo integrato, sia IDEA che quello integrato in JavaRush , esegue da solo questa "magia di avvio dell'app" - ndr ). Siamo onesti: nella maggior parte dei linguaggi di programmazione, lo script vero e proprio per l'esecuzione dei programmi sembra molto più semplice. JEP 330 elimina la necessità di compilare un'applicazione a file singolo, quindi ora se usi la riga di comando, digita semplicemente
java HelloWorld.java
Il programma di avvio Java rileverà che il file contiene codice sorgente Java e compilerà il codice in un file di classe prima di eseguirlo. È possibile inserire parametri dopo o prima del nome del file del codice sorgente. Quelli posti dopo il nome vengono passati come parametri quando viene eseguita l'applicazione. Quelli posti prima del nome vengono passati come parametri al launcher Java dopo la compilazione del codice. Anche le opzioni specifiche del compilatore (come classpath) verranno passate a javac per la compilazione. Esempio. Linea:
java -classpath / home / foo / java Hello.java Bonjour
sarà equivalente a queste righe:
javac -classpath / home / foo / java Hello.java
java -classpath / home / foo / java Hello Bonjour
[321] Client HTTP (standard) : il supporto dell'API client HTTP è stato standardizzato. JDK 9 ha introdotto una nuova API per supportare il protocollo client HTTP (JEP 110) . Poiché JDK 9 ha introdotto anche il Java Platform Module System (JPMS) , questa API è stata inclusa come modulo incubatore (si tratta di moduli per fornire agli sviluppatori nuove API che non sono ancora diventate standard in Java SE, mentre le API "live" vengono preparati per la rimozione: gli sviluppatori possono provare nuove API e provare a fornire feedback). Una volta apportate le modifiche necessarie (questa API è stata aggiornata in JDK 10), l'API può diventare parte dello standard. Pertanto, l'API client HTTP è ora ufficialmente inclusa in Java SE 11 . Questo introduce un nuovo modulo e pacchetto per JDK, java.net.http . I nuovi tipi principali sono: HttpClient HttpRequest HttpResponse WebSocket Questa API può essere utilizzata in modo sincrono o asincrono. In modalità asincrona, CompletionFuturese vengono utilizzati CompletionStages. [320] Rimuovere i moduli Java EE e CORBA Con l'introduzione del Java Platform Module System (JPMS) nella nona versione di Java, è diventato possibile dividere il file monolitico rt.jar in diversi moduli. Inoltre, JPMS ti consente di creare un ambiente runtime Java che include solo i moduli necessari alla tua applicazione, riducendone notevolmente le dimensioni. Con i limiti dei moduli definiti in modo trasparente, è molto più semplice rimuovere parti obsolete dell'API Java: questo è ciò che fa JEP 320. Il metamodulo java.se.ee include sei moduli che non faranno parte dello standard Java SE 11 e non saranno inclusi nel JDK:
  • corba
  • transazione
  • Attivazione
  • xml.bind
  • xml.ws
  • xml.ws.annotazione
Questi moduli erano deprecati in JDK 9 e non erano inclusi per impostazione predefinita nella compilazione o nell'esecuzione. Ciò significa che se hai provato a compilare o eseguire un'applicazione che utilizza le API di questi moduli su JDK 9 o JDK 10, l'operazione non è riuscita. Se utilizzi le API di questi moduli nel tuo codice, dovrai fornirli come modulo o libreria separata.

Nuove API

Un gran numero di nuove API in JDK 11 sono apparse grazie all'inclusione dei moduli HTTP Client e Flight Recorder nello standard del linguaggio . Per un elenco completo delle API, vedere il seguente confronto completo di diverse versioni del JDK , compilato da Gunnar Morling. E in questa nota elencheremo alcuni nuovi metodi che non sono inclusi nei moduli java.net.http , jdk.jfr e java.security . java.lang.String Probabilmente una delle modifiche più importanti a String nell'API JDK 11, ci sono diversi nuovi metodi utili.
  • boolean isBlank (): restituisce vero se la stringa è vuota o contiene solo spazi, falso altrimenti.

  • Stream lines(): Restituisce un flusso di righe estratte da questa stringa, separate da terminatori di riga.

  • String repeat (int): Restituisce una stringa il cui valore è la concatenazione di quella stringa ripetuta int volte.

  • String strip (): Restituisce una stringa con tutti gli spazi rimossi prima o dopo il primo carattere diverso dallo spazio.

  • String stripLeading (): Restituisce una stringa con tutti gli spazi rimossi fino al primo carattere diverso dallo spazio.

  • String stripTrainling (): Restituisce una stringa con tutti gli spazi che si trovano dopo la rimozione dell'ultimo carattere diverso dallo spazio.
strip()Il metodo ha già fatto qualcosa di simile trim (), ma per spazi questi metodi significano cose diverse. In tal caso trim()vengono tagliati solo gli spazi e strip()anche i caratteri speciali, come le tabulazioni. java.lang.StringBuffer java.lang.StringBuilder Entrambe queste classi contengono un nuovo metodo compareTo ()che accetta StringBuffer/ StringBuildere restituisce int. Il metodo del confronto lessicale è simile al nuovo metodo compareTo() CharSequence. java.io.ByteArrayOutputStream
  • void writeBytes (byte []): scrive tutti i byte del parametro nel flusso di output java.io.FileReader
Ci sono due nuovi costruttori qui che ti permettono di specificare Charset. java.io.FileWriter Quattro nuovi costruttori che consentono di specificare Charset. java.io.InputStream
  • io.InputStream nullInputStream (): restituisce InputStream, che non legge alcun byte. Come utilizzare questo metodo? Puoi pensarlo come qualcosa come /dev/null per buttare via l'output che non ti serve o per inserire input che restituisce sempre zero byte.
java.io.OutputStream
  • io.OutputStream nullOutputStream ()
java.io.Reader
  • io.Reader nullReader ()
java.io.Writer
  • io.Writer nullWriter ()
java.lang.Character
  • String toString (int): Questo è un sovraccarico di un metodo esistente, ma utilizza int invece di char.
java.lang.CharSequence
  • int compare (CharSequence, CharSequence): confronta lessicograficamente due istanze CharSequence. Restituisce un valore negativo, zero o un valore positivo se la prima sequenza è lessicograficamente inferiore, uguale o maggiore della seconda, rispettivamente.
java.lang.ref.Reference
    lang.Object clone (): L'evangelista di Java Simon Ritter ammette che questo metodo lo confonde. La classe Referencenon implementa un'interfaccia Cloneablee questo metodo genererà sempre un'eccezione CloneNotSupportedException. Tuttavia, l’esperto suggerisce che questo metodo sarà utile per qualcosa in futuro.
java.lang.Runtime java.lang.System Non ci sono nuovi metodi qui. Diciamo solo che il metodo runFinalizersOnExit ()è stato rimosso da entrambe queste classi, il che potrebbe causare problemi di compatibilità. java.lang.Thread Nessun metodo aggiuntivo, menzioneremo solo che destroy ()sono stop (Throwable)stati rimossi. Tuttavia stop (), che non accetta argomenti, è ancora disponibile. Tienilo presente perché potrebbero esserci problemi di compatibilità. java.nio.ByteBuffer java.nio.CharBuffer java.nio.DoubleBuffer java.nio.FloatBuffer java.nio.LongBuffer java.nio.ShortBuffer In tutte queste classi, gli sviluppatori del linguaggio hanno aggiunto un metodo mismatch ()che trova e restituisce l'indice relativo del prima mancata corrispondenza tra questo buffer e un dato buffer. java.nio.channels.SelectionKey
  • int interestOpsAnd (int)

  • int interestOpsOr (int)
java.nio.channels.Selector
  • int select (java.util.function.Consumer, long): seleziona ed esegue un'azione sui tasti i cui canali corrispondenti sono pronti per le operazioni di I/O. Il parametro lungo è un timeout.

  • int select (java.util.function.Consumer): funziona come il metodo sopra, ma senza timeout.

  • int selectNow (java.util.function.Consumer): funziona come il metodo sopra, solo che non è bloccante.

java.nio.file.Files
  • String readString (Path): legge tutto il contenuto di un file in una stringa, decodificando i byte in caratteri utilizzando la codifica UTF-8 .

  • String readString (Path, Charset): Funziona come il metodo sopra, ma decodifica i byte in caratteri utilizzando Charset.

  • Path writeString (Path, CharSequence, java.nio.file. OpenOption []): Se scrivi una sequenza di caratteri CharSequencein un file, tali caratteri verranno codificati in byte (utilizzando UTF-8 ).

  • Path writeString (Path, CharSequence, java.nio.file. Charset, OpenOption []): funziona come il metodo sopra, solo i caratteri vengono codificati in byte utilizzando Charset.
java.nio.file.Path
  • Path(String, String[]): Restituisce il Path, trasformando una stringa di percorso o una sequenza di stringhe che, se combinate, formano una stringa di percorso.

  • Path (net.URI): restituisce il percorso trasformando l'URI.
java.util.Collection
  • Object [] toArray (java.util.function.IntFunction): Restituisce un array contenente tutti gli elementi di questa raccolta, utilizzando la funzione generatrice fornita per distribuire l'array restituito.
java.util.concurrent.PriorityBlockingQueue java.util.PriorityQueue
  • void forEach (java.util.function.Consumer): esegue l'azione specificata su ciascun elemento Iterable finché tutti gli elementi non sono stati elaborati o l'azione genera un'eccezione.

  • boolean removeAll (java.util.Collection): rimuove tutti gli elementi di questa raccolta contenuti anche nella raccolta specificata (operazione facoltativa).

  • boolean removeIf (java.util.function.Predicate): rimuove tutti gli elementi di questa raccolta che soddisfano il predicato specificato.

  • boolean retainAll (java.util.Collection): preserva solo gli elementi di questa raccolta contenuti nella raccolta specificata (operazione facoltativa).
java.util.concurrent.TimeUnit
  • long convert (java.time.Duration): Converte la durata di tempo specificata in questa unità.
java.util.function.Predicate
  • Predicate not(Predicate): restituisce un predicato che è la negazione del predicato dato.
Ad esempio, il seguente codice:
lines.stream ()

.filter (s ->! s.isBlank ())
può essere convertito in questo:
lines.stream ()

.filter (Predicate.not (String :: ISBLANK))
e se usiamo l'importazione statica, questo è ciò che otteniamo:
lines.stream ()
.filter (not(String :: ISBLANK))
java.util.Optional java.util.OptionalInt java.util.OptionalDouble java.util.OptionalLong
  • boolean isEmpty (): Restituisce vero se non è presente alcun valore , falso altrimenti .
java.util.regex.Pattern
  • Predicate asMatchPredicate (): L'esperto Java Simon Ritter ritiene che qui potrebbe esserci un vero gioiello API JDK 11. Questo metodo crea un predicato che controlla se questo modello corrisponde a una determinata stringa di input.
java.util.zip.Deflater
  • int deflate (ByteBuffer): comprime i dati di input e riempie il buffer specificato con dati compressi.

  • int deflate (ByteBuffer, int): comprime i dati di input e riempie il buffer specificato con dati compressi. Restituisce la quantità effettiva di dati compressi.

  • void setDictionary (ByteBuffer): Imposta il dizionario dato da comprimere in byte nel buffer dato. Si tratta di un sovraccarico di un metodo esistente che ora può accettare un ByteBufferarray di byte anziché un array.

  • void setInput (ByteBuffer): Imposta i dati di input da comprimere. È anche un sovraccarico di un metodo esistente.
java.util.zip.Inflater
  • int inflate (ByteBuffer): Decomprime i byte nel buffer specificato. Restituisce il numero effettivo di byte non compressi.

  • void setDictionary (ByteBuffer): imposta il dizionario dato sui byte nel buffer dato. È una forma sovraccaricata di un metodo esistente.

  • void setInput (ByteBuffer): imposta i dati di input per la decompressione. Una forma sovraccaricata di un metodo esistente.
javax.print.attribute.standard.DialogOwner Questa è una nuova classe in JDK 11 ed è una classe di attributi utilizzata per supportare le richieste di pagine di stampa o personalizzazione da visualizzare in cima a tutte le finestre o in una finestra specifica. javax.swing.DefaultComboBoxModel javax.swing.DefaultListModel
  • void addAll (Collection): aggiunge tutti gli elementi presenti nella raccolta.

  • void addAll (int, Collection): aggiunge tutti gli elementi presenti nella raccolta, a partire dall'indice specificato.
javax.swing.ListSelectionModel
  • int [] getSelectedIndices (): Restituisce una matrice di tutti gli indici selezionati nel modello selezionato in ordine crescente.

  • int getSelectedItemsCount (): Restituisce il numero di elementi selezionati.
jdk.jshell.EvalException
  • shell.JShellException getCause (): Restituisce il motivo lanciabile nel client di esecuzione presentato da questa EvalException o null se il motivo non esiste o è sconosciuto.

Funzionalità non sviluppate da Java 11

[181] Controllo degli accessi basato su nidificazioni Java e altri linguaggi supportano classi nidificate tramite classi interne. Perché funzioni, il compilatore deve eseguire alcuni trucchi. Per esempio:
public class Outer {
    private int outerInt;

     class Inner {
       public void printOuterInt() {
         System.out.println("Outer int = " + outerInt);
       }
     }
   }
Il compilatore lo modifica per produrre qualcosa di simile prima della compilazione:
public class Outer {
      private int outerInt;

      public int access$000() {
        return outerInt;
      }

    }


    class Inner$Outer {

      Outer outer;

      public void printOuterInt() {
        System.out.println("Outer int = " + outer.access$000());
      }
    }
Sebbene logicamente la classe interna faccia parte dello stesso codice della classe esterna, viene compilata come una classe separata. Pertanto, questa operazione richiede un metodo di join sintetico che deve essere creato dal compilatore per fornire l'accesso al campo privato della classe esterna. Questo PEC introduce il concetto di nidi, in cui due membri dello stesso nido (Esterno e Interno nel nostro esempio) sono compagni di nidificazione. Sono definiti due nuovi attributi per il formato del file di classe: NestHost e NestMembers . Queste modifiche sono utili per altri linguaggi che supportano classi annidate e bytecode. Questa funzione introduce tre nuovi metodi per java.lang.Class : Class getNestHost () Class [] getNestMembers () boolean isNestmateOf (Class) [309] Costanti dinamiche del file di classe Questo JEP descrive un'estensione al formato del file di classe per supportare il nuovo modulo pool persistente CONSTANT_Dynamic. L'idea di una costante dinamica sembra un ossimoro, ma essenzialmente puoi pensarla come un valore finale in Java 11. Il valore di una costante di pooling non viene impostato in fase di compilazione (a differenza di altre costanti), ma utilizza un bootstrap metodo per determinare il valore al lead time. Pertanto il valore è dinamico, ma poiché il suo valore viene impostato una sola volta, è anche costante. Questa funzionalità è rivolta principalmente alle persone che sviluppano nuovi linguaggi e compilatori che genereranno bytecode e file di classe come output da eseguire sulla JVM. [315] Migliorare gli aspetti intrinseci di Aarch64 Questo JEP è stato proposto dalla comunità Red Hat. La JVM ora può utilizzare istruzioni più specializzate disponibili nel set di istruzioni Arm 64. In particolare, ciò migliora le prestazioni dei metodi , sin ()e cos ()della log ()classe java.lang.Math . [318] Epsilon: un Garbage Collector senza operazioni Come nel caso di JEP 315 , potete ringraziare Red Hat per l'introduzione del Garbage Collector Epsilon. Epsilon è insolito in quanto in realtà non raccoglie la spazzatura! Quando crea nuovi oggetti, alloca memoria se necessario, ma non recupera lo spazio occupato da oggetti non registrati. " Qual e il punto? ", - tu chiedi. Si scopre che questa “raccolta dei rifiuti” ha due usi:
  1. Innanzitutto, questo garbage collector è progettato per garantire che i nuovi algoritmi GC vengano valutati in termini di impatto sulle prestazioni. L'idea è di eseguire un'applicazione di esempio con Epsilon e generare una serie di parametri. Viene abilitato il nuovo algoritmo di Garbage Collection, vengono eseguiti gli stessi test e quindi i risultati vengono confrontati.

  2. Per attività molto brevi (si pensi alle funzioni serverless nel cloud) in cui puoi garantire di non superare la memoria allocata nell'heap. Ciò può migliorare le prestazioni eliminando il sovraccarico (inclusa la raccolta delle statistiche necessarie per decidere se eseguire il raccoglitore) nel codice dell'applicazione. Se lo spazio heap è esaurito, la JVM potrebbe essere configurata in modo errato in uno dei tre modi seguenti:
    • Normale si chiama OutOfMemoryError.
    • Eseguire un ripristino dell'heap
    • Il disco rigido JVM è guasto e potrebbe eseguire un'altra attività (come l'avvio di un debugger).
[328]: Flight Recorder Flight Recorder è un framework di acquisizione dati di basso livello per la JVM. Prima di JDK 11, questa era una funzionalità commerciale nel binario Oracle JDK. Oracle sta ora eliminando le differenze funzionali tra Oracle JDK e una build di OpenJDK. Ecco cosa fa Flight Recorder :
  • Fornisce un'API per la produzione e il consumo di dati come eventi
  • Fornisce un meccanismo buffer e un formato dati binario
  • Consente la personalizzazione e il filtraggio degli eventi
  • Fornire eventi per sistema operativo, JVM HotSpot e librerie JDK
Ci sono due nuovi moduli qui: jdk.jfr e jdk.management.jfr . [329] Algoritmi crittografici ChaCha20 e Poly1305 Questo JEP riguarda l'aggiornamento dei codici utilizzati dal JDK. Questo caso implementa gli algoritmi di crittografia ChaCha20 e ChaCha20-Poly1305 come specificato nella RFC 7539. ChaCha20 è un cifrario a flusso relativamente nuovo che può sostituire il vecchio e non sicuro cifrario RC4 . [333] ZGC: un Garbage Collector scalabile a bassa latenza Un Garbage Collector scalabile sperimentale a bassa latenza. Progettato per l'utilizzo con applicazioni che richiedono heap di grandi dimensioni (multigigabyte) e bassa latenza. Utilizza un heap di singola generazione ed esegue la maggior parte (ma non tutto) del lavoro di garbage collection contemporaneamente all'applicazione. [332] Transport Layer Security (TLS) 1.3 TLS 1.3 (RFC 8446) è una patch importante per il protocollo di sicurezza del livello di trasporto TLS che fornisce miglioramenti significativi in ​​termini di sicurezza e prestazioni rispetto alle versioni precedenti. Il JDK ora supporta questa versione del protocollo. Il materiale si basa su un articolo di Simon Ritter e sulla documentazione ufficiale .
Commenti
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION