Nessun risultato. Prova con un altro termine.
Guide
Notizie
Software
Tutorial

Java 8: le principali novità

Java 8: nuove caratteristiche e miglioramenti, maggiore produttività, incrementi significativi delle prestazioni, modelli di programmazione parallela semplificati e utilizzo più efficiente dei processori multi-core.
Java 8: nuove caratteristiche e miglioramenti, maggiore produttività, incrementi significativi delle prestazioni, modelli di programmazione parallela semplificati e utilizzo più efficiente dei processori multi-core.
Link copiato negli appunti

Java 8 è la prima edizione interamente Made in Oracle per cui vi era un'attesa alimentata da dubbi, timori e curiosità derivanti dall'acquisizione della Sun da parte di Oracle. L'attenzione di buona parte della comunità internazionale del software è ora volta a cercare di capire quale sarà l'effettivo supporto della Oracle al mondo Java e alla sua evoluzione, questa major release servirà a delinearne le prospettive.

Questa versione prometteva nuove caratteristiche e migliorie in diverse aree funzionali, maggiore produttività degli sviluppatori, incrementi significativi delle prestazioni mediante collezioni e annotazioni migliorate, modelli di programmazione parallela semplificati e utilizzo più efficiente dei processori multi-core.

Nel corso di questa trattazione vedremo cosa ci offre di nuovo Java 8. La prima osservazione che possiamo fare è che il numero di packages della Standard Edition è aumentato leggermente, dai 209 della versione precedente agli attuali 217.

Espressioni Lambda e metodi default

Le espressioni Lambda costituiscono la principale novità per il linguaggio di programmazione Java. Il focus in Java è sempre stato sui dati (classi, ereditarietà, generics, etc.), con questa particolare funzione l'attenzione si muove verso il comportamento.

Si è visto che volendo modellare un flusso del tipo "fai A prima di iniziare, quindi effettua B per ogni file in questo gruppo, C se individui un errore, e infine D quando hai finito", non vi sono strumenti idonei a esprimere tale comportamento e ciò impatta sulle API, ad esempio costringendo il codice client ad un coinvolgimento diretto in ogni passo.

Le espressioni lambda sono lo strumento individuato per superare questo problema. Sono collegate al concetto di funzione anonima, ossia una funzione che ha un corpo ma non un nome. Un'espressione lambda definisce una funzione anonima che mantiene lo stato. In pratica un metodo senza una dichiarazione e quindi senza nome, modificatori d'accesso, dichiarazione del tipo del valore di ritorno.

La loro sintassi è qualcosa di simile:

(arg1, arg2) -> {body}

Ad esempio:

(int a, int b) -> {return a+b;}

Volendo confrontare codice scritto senza e con le espressioni lambda, osserviamo l'implementazione del comportamento di un pulsante prima e dopo.

//Prima:
button.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Sintassi arcinota!");
}
});
//Dopo:
button.addActionListener( (e) -> {
System.out.println("Nuova sintassi!");
});

Di seguito un altro esempio in cui utilizziamo l'espressione lambda per una semplice stampa a video. L'espressione lambda compare due volte, la prima come fatto in precedenza, nella seconda invece vediamo che è possibile convertire un metodo normale in una espressione lambda mediante l'operatore doppio due punti (::).

//Prima:
List list1 = Arrays.asList(1,2,3,5);
for(Integer n: list1) {
System.out.println(n);
}
//Dopo:
List list2 = Arrays.asList(1,2,3,5);
list2.forEach(n -> System.out.println(n));
//Espressioni lambda e doppio due punti
list2.forEach(System.out::println);

Altra novità per il linguaggio Java è costituita dai metodi default, nuove funzionalità che possono essere aggiunte alle interfacce delle librerie. E' ora possibile aggiungere nuovi metodi alle interfacce garantendo al contempo la compatibilità dei compilati con codice scritto per vecchie versioni delle interfacce (retrocompatibilità). Come immaginabile dal nome, le classi che implementano l'interfaccia ma non effettuano l'override del metodo in caso di invocazione di tale metodo offriranno l'implementazione di default.

Nashorn e Javascript

Nashorn permette a Java 8 di eseguire JavaScript sulla JVM. Nashorn è un engine incluso nella JDK per permettere a qualsiasi applicazione Java di contenere parti scritte in JavaScript. Inoltre, un tool a riga di comando (jjs) permette agli sviluppatori di usare Nashorn come tool di scripting consentendo la generazione di applicazioni JavaScript autoportanti. In pratica, va ad occupare il posto di Rhino, JavaScript engine anch'esso Open Source, promettendo migliori performance e un'integrazione maggiore tra mondo Java e mondo JavaScript.

L'idea è che gli sviluppatori di JavaScript possano utilizzare la ricchezza di librerie presenti in Java e implementare caratteristiche dinamiche bypassando cicli di build, mentre gli utenti possono cambiare configurazioni evitando di rigenerare l'applicazione.

Profili compatti

Avete sempre desiderato di potere istanziare un sottoinsieme della piattaforma Java? I profili compatti permettono di farlo, consentendo alle applicazioni che non richiedono l'intera piattaforma di essere lanciate anche su dispositivi dalle capacità ridotte.

Tutto ciò si è ottenuto tramite l'identificazione di tre sottoinsiemi delle API di Java 8, offrendo la convergenza tra Java ME CDC (Connected Device Configuration) e Java 8. Il più piccolo di questi profili (denominati compact1, compact2 e compact3) richiede attorno agli 11 MB, ossia meno di quattro volte del tradizionale JRE (Java Runtime Environment), evidentemente pensato per lavorare su piattaforme con vincoli pressanti in termini di risorse disponibili o di performance / tempi di start up. Inoltre, l'eliminazione di codice inutilizzato può risultare utile dal punto di vista della prospettiva della sicurezza e per ridurre i tempi di download delle applicazioni.

Il timore lato Sun/Oracle si basa sul rischio di una eccessiva frammentazione della Java SE, con la prospettiva di infinite varianti e sotto varianti praticamente ingestibili. Ma i vantaggi hanno prevalso sui timori e si è proceduto a questa prima suddivisione delle librerie, anche se l'implementazione completa del concetto di piattaforma modulare è da rimandarsi a Java 9. E di fatti parliamo di profili e non di moduli, dove ogni profilo è un insieme che include il precedente (compact2 include compact1, e compact3 include compact2, includendo pertanto anche compact1).

Se guardiamo alle librerie incluse nei vari profili, nel profilo base troveremo tra le altre le immancabili java.io, java.lang, java.net e java.util, oltre alle librerie per la sicurezza java.security e javax.security. Nel secondo profilo si evidenza la presenza di java.rmi, java.sql e buona parte delle librerie per l'XML. Nel terzo profilo compaiono le javax.management, javax.naming e javax.xml.crypto.

Abbiamo visto che il profilo più compatto si attesta attorno agli 11 MB. Il maggiore attorno ai 21 MB, ben al di sotto della metà di una classica Java SE 7.

Nella prossima e ultima parte di questa trattazione concluderemo il nostro discorso su Java 8 introducendo alcune altre novità rilevanti di tale aggiornamento.

API per date, tempo e streams

Java 8 introduce una nuova libreria per rappresentare il tempo, java.time, pensata per fornire supporto per lo standard internazionale ISO 8601, introdurre nuove funzionalità e superare alcuni problemi riscontrati con le vecchie API. Le nuove classi hanno ruoli specifici (Clock, Year, YearMonth..) e i tipi sono immutabili per semplificare la gestione della concorrenza in ambienti multitask. Ciò evidentemente è in contrasto con quanto avviene con le classiche Date e Calendar basate su dati modificabili che non godono della thread safety e, soprattutto, non sono propriamente intuitive (in java.util.Date, ad esempio, i mesi partono da 1 mentre i giorni da 0).

Si è deciso quindi di dare ascolto alle richieste per una nuova API in grado di ovviare ai problemi delle librerie precedenti, unendo gli sforzi con quelli dell'autore di una popolare libreria non nativa, la Joda-Time.

Per gestire il concetto di differenza di tempo, vengono introdotte due classi, Duration e Period, che consentono di esprimere e facilitare il calcolo di intervalli temporali. Period è ottenibile infatti come differenza tra tempi (.between(time1, time2)), mentre Duration come differenza tra date (.between(date1, date2)).

Per quanto riguarda le collezioni, Java SE 8 introduce il nuovo package java.util.streams, pensato per offrire supporto alle operazioni che riguardano flussi di elementi. L'API Stream è integrata con le API Collections, consentendo operazioni massive sulle collezioni di dati. Non è pensata per soppiantare ArrayLists o altre collezioni, ma per manipolare i dati in maniera più semplice e veloce, tramite un oggetto da usare una volta e a senso unico. Similmente all'iterator, con lo stream rappresentiamo una sequenza di oggetti. Ma, a differenza dell'iterator, oltre ad operazioni sequenziali lo stream supporta operazioni parallele (consentendo di sfruttare al meglio le moderne architetture multicore). Per quanto riguarda i pattern supportati, gli streams sono pensati per eseguire operazioni di filtraggio, mapping e riduzioni.

JavaFX 8

JavaFX, un insieme di librerie create per lo sviluppo e la distribuzione di moderne applicazioni Web su piattaforme eterogenee, è divenuta parte integrante della piattaforma Java (di qui il codice versione passato direttamente ad otto). Vi troveremo un nuovo tema di default ("Modena"), un linguaggio dichiarativo per realizzare interfacce utente a partire dal FXML (linguaggio basato sull'XML per creare interfacce utente separandone la logica applicativa), un componente in grado di integrare applicazioni FX nelle pagine Web, API per gestire la stampa e nuove API per gestire la grafica tridimensionale, il supporto per schermi HiDPI e il supporto potenziato per il testo.

Tramite l'utilizzo delle espressioni lambda la gestione del codice dovrebbe risultare semplificata. Inoltre, JavaFX 8 offre un supporto migliorato per componenti di terze parti. Infine, vengono dichiarati progressi significativi sul fronte delle performance.

Coinvolgimento della community

La comunità Java è stata fondamentale per identificare nuove funzionalità e requisiti da soddisfare, scoprire bugs, presentare soluzioni utili a migliorare Java 8. Tramite il JCP (Java Community Process) si sta organizzando la spinta propositiva e il desiderio di contribuire al mondo Java. In particolare, anche tramite iniziative quali "Adotta un programma JSR", si sta rendendo più semplice e trasparente contribuire ed essere coinvolti nelle attività che orbitano attorno al mondo Java. In evidenza i JUGs (Java User Groups), nodi essenziali nel processo di apprendimento, partecipazione e testing della community.

Java ME 8

Assieme ad un drastico aumento di dispositivi che necessitano dell'accesso ad internet si sta registrando anche l'aumentare della frammentazione delle architetture hardware, dei sistemi software e delle infrastrutture di supporto, con il risultato di assistere a sviluppi e standard interamente pensati per una specifica periferica. Con Java 8 si cerca invece di fare un passo per contenere la frammentazione, come già visto con i profili compatti, muovendosi verso la convergenza tra Java SE 8 e Java ME 8.

Java Micro Edition 8 si propone di fornire un ambiente di sviluppo e di esecuzione specializzato, scalabile e flessibile per periferiche di ogni tipo. Tutto ciò includendo standard, linguaggi, strumenti di sicurezza (e una comunità di oltre 9 milioni di sviluppatori pronti ad offrire il proprio sostegno), basando l'intero stack su uno strato (CLDC, Connected Limited Device Configuration, 8) pensato per allineare Java SE 8 e Java ME 8 in termini di strumenti e modello di programmazione, oltre a fornire nuove caratteristiche utili per specifici ambienti.

CLDC 8 offre i recenti costrutti del linguaggio Java, come annotazioni e generics. Tenendo presente i sottoinsieme di costrutti e API comuni, sarà possibile creare applicazioni o librerie in grado di essere eseguite senza modifiche su un vasto spettro di dispositivi, dai device ultra ridotti a quelli creati per il mondo desktop o server.

JVM e sicurezza

L'attenzione in questa nuova versione della JVM è focalizzata su un garbage collector più maturo ed efficiente, in grado di effettuare in maniera concorrente un carico di lavoro maggiore. Il design di base non è stato cambiato ma soggetto a un miglioramento incrementale, correggendo le discrepanze individuate nei flags correlati con il garbage collector.

Altro aspetto finalmente affrontato, la gestione dell'area della permanent generation. Si tratta di un'area utilizzata dall'HotSpot VM per mantenere metadati relativi a classi, strutture dati etc., soggetta ad essere sovraccaricata al crescere dell'utilizzo di librerie di terze parti, con conseguenti errori di OutOfMemory e richieste di aumento del MaxPermSize. La rappresentazione delle classi nell'HotSpot VM è stata reingegnerizzata, rimossa dall'area della permanent generation e spostata verso le aree di memoria nativa o verso l'heap. Pertanto, gli sviluppatori non dovranno più preoccuparsi di stabilire dimensioni adeguate per la permanent generation.

Per quanto riguarda la sicurezza, vi sono diverse novità. Tra tutte, algoritmi più resistenti per la crittografia, supporto incrementato per la gestione delle chiavi con una nuova opzione (-importpassword) per le istruzioni a riga di comando utile a importare e memorizzare in modo sicuro le chiavi (oltre a classi aggiunte o modificate per migliorarne la gestione), l'implementazione di una nuova variante di funzione crittografica di hash (SHA-224).

La novità principale riguarda l'attivazione di default di TLS 1.2 (Transport Layer Security) sul lato client. Si tratta di un protocollo di crittografia che consente la comunicazione sicura; esso è stato progettato per criptare le comunicazioni, assicurando che nessuno possa leggerle o modificarle, ed è combinabile con i certificati per stabilire un livello di confidenza.

TLS era già presente e attivo lato server di default dalla JDK 7, ma per ragioni di retrocompatibilità non era attivo di default lato client. TLS 1.2 è stato invece impostato di default sulla JDK 8 anche lato client contando su una maggiore maturità raggiunta dal settore in termini di interoperabilità e retro compatibilità e, soprattutto, contando sulla retrocompatibilità di TLS (la versione 1.2 è compatibile con la 1.1 e 1.0) e sfruttandone la trasparenza rispetto alle altre applicazioni. In questo modo si è potuto migliorare il livello di sicurezza delle comunicazioni rispetto alle intercettazioni.

Ti consigliamo anche