JavaRush /Java Blog /Random-IT /Java 13: nuove funzionalità

Java 13: nuove funzionalità

Pubblicato nel gruppo Random-IT
Ci siamo già abituati al fatto che ogni sei mesi esce una nuova versione di JDK. Finora questo approccio si è giustificato e le preoccupazioni di alcuni sviluppatori di non tenere il passo con gli aggiornamenti sono state vane: ci sono pochi cambiamenti semestrali e non sono così globali come prima. Ebbene, i programmatori alle prime armi potrebbero non notare affatto l'innovazione. Java 13: nuove funzionalità - 1Tuttavia, è meglio che i futuri sviluppatori di software si tengano al passo con le innovazioni. In questo articolo descriveremo tradizionalmente le proposte di estensione accettate (JEP). Java 13 include solo cinque JEP e 76 nuovi elementi della libreria principale (di cui quasi la metà sono semplici aggiunte al pacchetto java.io).

JEP 355 : Blocchi di testo (Anteprima)

Cominciamo cambiando la sintassi del linguaggio. I più significativi sono i blocchi di testo. Ti consentono di evitare caratteri di escape e di sapere come formattare le stringhe. Potresti ricordare che JDK 12 non includeva la funzionalità Raw String Literals (JEP 326) prevista per lavorare con stringhe letterali. In Java 13 è stato sostituito da JEP 355 con i suoi blocchi di testo. Probabilmente ricorderai che in Java una stringa è racchiusa tra virgolette doppie. Questo è positivo, ma il problema è che una riga non può occupare più di una riga del file sorgente (per evitare confusione con una riga Java, qui chiameremo una riga di file “riga”). Bene, facciamo un giro e utilizziamo, ad esempio, il simbolo \nse è richiesta un'interruzione o la concatenazione di espressioni su più righe. Non viene molto bene! I valori letterali di testo con frammenti HTML, XML, SQL o JSON incorporati sono particolarmente ingombranti. Tutto questo escape, concatenazione e modifica manuale rende il codice scomodo da scrivere e difficile da leggere. I blocchi di testo tentano di risolvere questo problema. Iniziano uh... con virgolette triple e finiscono con esse (lo so, non suona molto bene). Tutto ciò che è tra virgolette viene interpretato come parte della riga, compresi i ritorni a capo. I blocchi di testo possono essere utilizzati esattamente come valori letterali di testo standard e Java compilerà il codice nello stesso modo. Le virgolette di apertura devono essere seguite da un delimitatore di riga; i blocchi di testo non possono essere utilizzati in una riga, quindi il codice
String smallBlock = """Only one line""";
porterà ai seguenti errori:
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
   String smallBlock = """Text Block""";
                          ^
TextBlock.java:3: error: illegal text block open delimiter sequence, missing line terminator
   String smallBlock = """Text Block""";
                                   	^
Un semplice frammento HTML può ora essere scritto in questo modo:
String htmlBlock = """
               	<html>
                 	<body>
                   	<p>CodeGym Web page</p>
                 	</body>
               	<html>
         	     """;
Citiamo alcune sottigliezze di cui è meglio essere consapevoli quando si utilizzano blocchi di testo. Il posizionamento delle virgolette di chiusura risulta essere importante: determina come vengono gestiti gli spazi bianchi occasionali. Nell'esempio sopra, le virgolette di chiusura sono allineate con il rientro del testo HTML. In questo caso il compilatore rimuoverà gli spazi di rientro e di conseguenza otterremo una riga come questa:
<html>
  <body>
    <p>My web page</p>
  </body>
</html>
Nota:tale riga conterrà un ritorno a capo alla fine della riga. Se non è necessario, le virgolette chiuse “”” possono essere inserite direttamente dopo il tag </html>. Se spostiamo le virgolette di chiusura più vicino al margine sinistro, ciò cambierà la quantità di rientro rimosso. Se li spostassimo di due spazi a sinistra, aggiungeremmo due spazi per il rientro su ciascuna riga. Lo spostamento sul bordo sinistro farà sì che tutta la spaziatura interna venga preservata. Lo spostamento delle virgolette più a destra non avrà alcun effetto e non aggiungerà ulteriori rientri. I blocchi di testo sono stati inclusi in JDK 13 come funzionalità di anteprima. Ciò significa che non sono ancora inclusi nella corrispondente specifica del linguaggio Java. Cioè, non è chiaro se questa caratteristica diventerà una parte permanente della lingua o se qui sarà solo un ospite. Attualmente, gli sviluppatori possono testare la funzionalità e dare la loro opinione al riguardo. Il destino dei blocchi di testo dipenderà da questo: la funzionalità può essere migliorata e, se non ti piace, può essere rimossa del tutto. Se vuoi provare nella pratica i blocchi di testo, ricorda che le funzionalità di anteprima devono essere incluse esplicitamente per poter essere compilate ed eseguite. Compilazione:

javac --enable-preview --release 13 TextBlock.java
Per eseguire l'applicazione, è necessario abilitare le funzionalità di anteprima:

java --enable-preview TextBlock
La classe Stringha tre nuovi metodi che completano questo cambiamento di linguaggio:
  • formatted(): formatta una stringa utilizzando la stringa stessa come stringa di formato. Equivalente ad una sfidaformat(this, args)
  • stripIndent(): rimuove gli spazi casuali da una stringa. Ciò è utile se stai leggendo stringhe su più righe e desideri applicare la stessa esclusione degli spazi bianchi come faresti con una dichiarazione esplicita.
  • translateEscapes(): Restituisce una stringa con sequenze di escape (come \ r), tradotta nel valore Unicode appropriato.
È interessante notare che questi metodi sono appena apparsi, ma sono già contrassegnati come deprecati ... questo stato di cose suggerisce che potrebbero essere rimossi in una futura versione del JDK. Sembra un po’ eccentrico aggiungere un nuovo metodo e abbandonarlo subito. Tuttavia, tieni presente che questi metodi sono associati a una funzionalità di anteprima che può essere modificata o rimossa. Forse introdurre un'annotazione @PreviewFeatureaiuterebbe in tali situazioni, ma non è ancora inclusa nel JDK (anche se con un alto grado di probabilità apparirà nel JDK 14).

JEP 354 : Cambia espressione (anteprima)

Java 12 ha introdotto una proposta per una nuova forma di scrittura delle espressioni con un'istruzione switch: JEP 325 . Si è rivelata la primissima funzionalità di anteprima e il suo destino dimostra che presentare proposte agli utenti è un'ottima idea. Prima del JDK 12, switchpoteva essere utilizzato solo come istruzione che esegue un'azione ma non restituisce un risultato. Ma in Java 12 ne è consentito l'utilizzo switchcome espressione che restituisce un risultato che può essere assegnato a una variabile. Sono state apportate altre modifiche alla sintassi delle istruzioni case all'interno di switch. Diamo un'occhiata a un esempio tratto da JEP per capire come funziona.
int numberOfLetters;
switch(dayOfWeek) {
  case MONDAY:
  case FRIDAY:
  case SUNDAY:
    numberOfLetter = 6;
    break;
  case TUESDAY
    numberOfLetter = 7;
    break;
  case THURSDAY
  case SATURDAY
    numberOfLetter = 8;
    break;
  case WEDNESDAY
    numberOfLetter = 9;
    break;
  default:
   throw new IllegalStateException("Huh?: " + day);
}
In questo esempio, utilizziamo value dayOfWeekper assegnare il valore a numberOfLetters. A causa delle peculiarità del lavoro dell'operatore switch, questo codice non è dei più belli ed è facile commettere errori. Innanzitutto, se dimentichiamo di applicare un'istruzione breaka ciascun gruppo di etichette di casi, passeremo per impostazione predefinita al gruppo successivo di etichette di casi. Ciò può portare a errori difficili da trovare. In secondo luogo, dobbiamo definire ciascun gruppo di etichette di casi. Se dimentichiamo, ovviamente otterremo un errore del compilatore, tuttavia questa opzione non è l'ideale. Il nostro codice è anche piuttosto dettagliato perché ogni valore dayOfWeekdeve avere la propria etichetta maiuscole e minuscole. Usando la nuova sintassi, otteniamo un codice molto più pulito e meno soggetto a errori:
int numberOfLetters = switch (dayOfWeek) {
   case MONDAY, FRIDAY, SUNDAY -> 6;
   case TUESDAY -> 7;
   case THURSDAY, SATURDAY -> 8;
   case WEDNESDAY -> 9;
   default -> throw new IllegalStateException("Huh?: " + day);
};
Ora dobbiamo effettuare l'assegnazione solo una volta (dal switchvalore restituito dall'espressione) e possiamo utilizzare un elenco separato da virgole per le etichette dei casi. E poiché non utilizziamo l'operatore break, eliminiamo i problemi ad esso associati. La sintassi dell'espressione switchci consente di utilizzare la sintassi di vecchio stile, quindi in JDK 12 possiamo scriverla in questo modo:
int numberOfLetters = switch (dayOfWeek) {
  case MONDAY:
  case FRIDAY:
  case SUNDAY:
   break 6;
  case TUESDAY
   break 7;
  case THURSDAY
  case SATURDAY
   break 8;
  case WEDNESDAY
   break 9;
  default:
   throw new IllegalStateException("Huh?: " + day);
};
Secondo la comunità Java, l'utilizzo dell'overloading breakper specificare un valore restituito può creare confusione. Il linguaggio Java consente inoltre di utilizzare break( e continue) con un'etichetta come l'operatore di salto incondizionato goto. JEP 354 ha cambiato questo utilizzo break, quindi in Java 13 il nostro codice cambia leggermente:
int numberOfLetters = switch (dayOfWeek) {
  case MONDAY:
  case FRIDAY:
  case SUNDAY:
   yield 6;
  case TUESDAY
   yield 7;
  case THURSDAY
  case SATURDAY
   yield 8;
  case WEDNESDAY
   yield 9;
  default:
   throw new IllegalStateException("Huh?: " + day);
};
I successivi tre JEP sono associati alla Java Virtual Machine.

Archivio CDS dinamico JEP 350

Questa estensione consente di archiviare dinamicamente le classi al termine dell'esecuzione di un'applicazione Java. CDS o Class Data Sharing ti consente di comprimere tutte le classi avviate all'avvio in un archivio speciale class data sharing, utilizzando l'elenco di queste stesse classi per impostazione predefinita. Ciò porta ad una significativa accelerazione nell'avvio delle applicazioni e nel risparmio della RAM. In precedenza, l'utilizzo di AppCDS era un processo in più fasi che prevedeva la creazione di un elenco di classi pertinenti e l'utilizzo di tale elenco per creare un archivio da utilizzare per le esecuzioni successive. Ora tutto ciò che serve è un avvio dell'applicazione con il flag -XX: ArchiveClassesAtExitche indica la posizione in cui verrà scritto l'archivio. Con questo approccio, le classi vengono automaticamente inserite in un archivio dopo che l'applicazione viene arrestata normalmente.

JEP 351 ZGC : sblocca la memoria inutilizzata

Un anno fa, JDK 11 ha introdotto ZGC, un garbage collector sperimentale, scalabile e a bassa latenza. All'inizio ZGC si comportava in modo piuttosto strano: non permetteva di restituire memoria al sistema operativo, anche se non era più necessaria. Per alcuni ambienti, come i contenitori, in cui le risorse vengono utilizzate da più servizi contemporaneamente, ciò potrebbe limitare la scalabilità e l'efficienza del sistema. L'heap ZGC è costituito dalle cosiddette ZPage. Quando le ZPage vengono cancellate durante il ciclo di garbage collection, vengono restituite a ZPageCache. Le ZPage in questa cache sono ordinate in base a quanto recentemente sono state utilizzate. In Java 13, ZGC restituirà al sistema operativo le pagine identificate come non utilizzate da molto tempo. In questo modo possono essere riutilizzati per altri processi.

JEP 353 Reimplementare l'API Socket legacy

Entrambe le implementazioni API java.net.Socketsono java.net.ServerSocketancora JDK 1.0. In questo e in tutti i successivi JDK, l'implementazione di queste API utilizza diverse tecniche (come l'utilizzo dello stack di thread come buffer I/O) che le rendono poco flessibili e difficili da mantenere. Per risolvere questo problema, è stata fornita una nuova implementazione in JDK 13 NioSocketImpl. Non richiede più codice nativo, rendendo più semplice il porting su piattaforme diverse. Questa classe utilizza anche il meccanismo di cache del buffer esistente (evitando l'uso dello stack di thread per questo scopo) e java.util.concurrentmetodi di blocco anziché sincronizzati. Ciò semplificherà l'integrazione con le fibre di Project Loom .

Nuove API

Abbiamo accennato in precedenza che Java 13 include 76 nuove API nelle librerie di classi base. Coprono le seguenti aree:
  • Aggiornamenti del supporto Unicode.
  • Tre nuovi metodi Stringper supportare i blocchi di testo (vedere la descrizione JEP 255 sopra).
  • Le classi java.nioora hanno assoluto (in contrapposizione a relativo) gete impostare metodi. Essi, come la classe astratta di base Buffer, includono un metodo slice()per recuperare parte del buffer.
  • Il metodo force()della classe MappedByteBufferforza la scrittura di una sezione del buffer nella memoria di backup.
  • nio.FileSystemaggiunge tre nuovi moduli sovraccarichi newFileSystem()per accedere al contenuto di un file come file system.
  • È javax.annotation.processing.ProcessingEnvironmentapparso un nuovo metodo interessante. isPreviewEnabled(). Ti dirà se le funzionalità di anteprima sono abilitate. Ciò è interessante perché l'annotazione sopra menzionata @PreviewFeaturenon sarà disponibile fino al rilascio di JDK 14.
  • DocumentBuilderFactorye SAXParserFactoryottieni javax.xml.parserstre nuovi metodi per creare istanze che riconoscono lo spazio dei nomi.
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