Java 9 - Guida rapida
JAVA 9 (aka jdk 1.9) è una versione importante dello sviluppo del linguaggio di programmazione JAVA. La sua versione iniziale è stata rilasciata il 21 settembre 2017. Gli obiettivi principali del rilascio di Java 9 sono:
Rendere la piattaforma JDK e Java Standard Edition modulare, nel senso che può essere ridotta a piccoli dispositivi di elaborazione.
Per migliorare la sicurezza complessiva delle implementazioni JDK e Java.
Per rendere il processo di compilazione e la manutenzione di librerie di codici java e applicazioni di grandi dimensioni facili per piattaforme JAVA SE ed EE.
Progettare e implementare un sistema di moduli standard per la piattaforma Java che può essere applicato facilmente sia sulla piattaforma che su JDK.
Nuove caratteristiche
Ci sono oltre 90 miglioramenti aggiunti a Java 8, i più significativi sono menzionati di seguito:
Module - Un nuovo tipo di componente di programmazione Java introdotto come modulo, che è una raccolta denominata e auto-descrittiva di codice e dati.
REPL (JShell) - Funzionalità REPL (Read-Eval-Print Loop) aggiunta alla piattaforma Java.
HTTP 2 Client - nuova API HTTPClient che supporta websocket e flussi HTTP 2 e funzionalità server push.
Improved JavaDocs- Supporta la generazione di output HTML5. Fornisce una casella di ricerca per la documentazione API generata.
Multirelease JAR - Migliora il formato JAR in modo che più versioni specifiche di Java dei file di classe possano coesistere in un unico archivio.
Collection Factory Methods - Nuovi metodi factory statici per le interfacce List, Set e Map per creare istanze immutabili di tali raccolte.
Private Interface Methods - Interfacce migliorate con metodi statici privati e privati.
Process API Improvements - API migliorata per controllare e gestire i processi del sistema operativo.
Stream API Improvements - Maggiore sicurezza e robustezza consentendo di filtrare i flussi in entrata dei dati di serializzazione degli oggetti.
Try With Resources improvement - Ora le variabili finali possono essere utilizzate come risorse nell'istruzione try-with-resources.
Enhanced @Deprecated Annotation - @ Annotazione obsoleta rinnovata per fornire ulteriori informazioni sullo stato e sulla disposizione prevista di un'API.
Inner Class Diamond Operator - Consenti l'utilizzo dell'operatore diamante con classi anonime se è possibile indicare il tipo di argomento del tipo dedotto.
Optional Class Improvements - Nuovi metodi utili vengono aggiunti alla classe java.util.Optional.
Multiresolution Image API - Supporta l'incapsulamento di una serie di immagini con diverse risoluzioni in un'unica immagine multirisoluzione.
CompletableFuture API improvements - I meccanismi asincroni della classe CompletableFuture possono eseguire un'azione quando il processo esce con il metodo ProcessHandle.onExit.
Lightweight JSON - Un'API leggera introdotta per consumare e generare documenti e flussi di dati tramite json in java 9.
Reactive Streams API - È stata introdotta una nuova API Reactive Streams in Java SE 9 per supportare la programmazione reattiva in java 9.
Configurazione dell'ambiente locale
Se desideri configurare il tuo ambiente per il linguaggio di programmazione Java, questa sezione ti guida attraverso l'intero processo. Seguire i passaggi indicati di seguito per configurare il proprio ambiente Java.
Java SE è disponibile per il download gratuito. Per scaricare clicca qui , scarica una versione compatibile con il tuo sistema operativo.
Segui le istruzioni per scaricare Java ed esegui il file .exeper installare Java sulla tua macchina. Dopo aver installato Java sulla macchina, sarà necessario impostare le variabili di ambiente in modo che puntino alle directory di installazione corrette.
Impostazione del percorso per Windows 2000 / XP
Supponendo che tu abbia installato Java nella directory c: \ Program Files \ java \ jdk -
Fare clic con il pulsante destro del mouse su "Risorse del computer" e selezionare "Proprietà".
Fare clic sul pulsante "Variabili d'ambiente" nella scheda "Avanzate".
Ora, modifica la variabile "Path" e aggiungi il percorso alla directory eseguibile Java alla fine di essa. Ad esempio, se il percorso è attualmente impostato su
C:\Windows\System32
, modificalo nel modo seguente
C:\Windows\System32;c:\Program Files\java\jdk\bin
Impostazione del percorso per Windows 95/98 / ME
Supponendo che tu abbia installato Java nella directory c: \ Program Files \ java \ jdk -
Modifica il file "C: \ autoexec.bat" e aggiungi la seguente riga alla fine:
SET PATH = %PATH%;C:\Program Files\java\jdk\bin
Configurazione del percorso per Linux, UNIX, Solaris, FreeBSD
La variabile d'ambiente PATH dovrebbe essere impostata in modo che punti a dove sono stati installati i binari Java. Fare riferimento alla documentazione della shell se si hanno problemi a farlo.
Ad esempio, se usi bash come shell, aggiungi la seguente riga alla fine del tuo .bashrc -
export PATH = /path/to/java:$PATH'
Editor Java popolari
Per scrivere programmi Java, è necessario un editor di testo. Sul mercato sono disponibili IDE ancora più sofisticati. I più popolari sono descritti brevemente di seguito:
Notepad- Su una macchina Windows, puoi usare qualsiasi semplice editor di testo come Blocco note (consigliato per questo tutorial) o WordPad. Notepad ++ è anche un editor di testo gratuito che migliora le funzionalità.
Netbeans - È un IDE Java open-source e gratuito da cui è possibile scaricare https://www.netbeans.org/index.html.
Eclipse - È anche un IDE Java sviluppato dalla comunità open source di Eclipse e può essere scaricato da https://www.eclipse.org/.
IDE o Integrated Development Environment, fornisce tutti gli strumenti e le strutture comuni per aiutare nella programmazione, come editor di codice sorgente, strumenti di compilazione e debugger ecc.
Java 9, è stato introdotto un nuovo tipo di componente di programmazione chiamato module. Un modulo è una raccolta di codice e dati che si autodefinisce e ha un nome per identificarlo.
Caratteristiche
Con il componente Modules, sono stati aggiunti i seguenti miglioramenti in Java 9:
Viene introdotta una nuova fase facoltativa, il tempo di collegamento. Questa fase è intermedia tra il tempo di compilazione e il tempo di esecuzione. Durante questa fase, un set di moduli può essere assemblato e ottimizzato, creando un'immagine runtime personalizzata utilizzando lo strumento jlink.
javac, jlink e java hanno opzioni aggiuntive per specificare i percorsi dei moduli, che individuano ulteriormente le definizioni dei moduli.
Formato JAR aggiornato come JAR modulare, che contiene il file module-info.class nella sua directory principale.
Introduzione del formato JMOD, un formato di packaging (simile a JAR) che può includere codice nativo e file di configurazione.
Creazione del modulo
Seguendo i passaggi per creare un modulo, dì com.tutorialspoint.greetings.
Passo 1
Crea una cartella C: \> JAVA \ src. Ora crea una cartella com.tutorialspoint.greetings che è uguale al nome del modulo che stiamo creando.
Passo 2
Crea module-info.java in C: \> JAVA \ src \ com.tutorialspoint.greetings cartella con il seguente codice.
module-info.java
module com.tutorialspoint.greetings { }
module-info.java è il file che viene utilizzato per creare il modulo. In questo passaggio abbiamo creato un modulo denominato com.tutorialspoint.greetings. Per convenzione questo file dovrebbe risiedere nella cartella il cui nome è uguale al nome del modulo.
Passaggio 3
Aggiungi il codice sorgente nel modulo. Crea Java9Tester.java nella cartella C: \> JAVA \ src \ com.tutorialspoint.greetings \ com \ tutorialspoint \ greetings con il seguente codice.
Java9Tester.java
package com.tutorialspoint.greetings;
public class Java9Tester {
public static void main(String[] args) {
System.out.println("Hello World!");
}
}
Per convenzione, il codice sorgente di un modulo deve trovarsi nella stessa directory che è il nome del modulo.
Passaggio 4
Crea una cartella C: \> JAVA \ mods. Ora crea una cartella com.tutorialspoint.greetings che è uguale al nome del modulo che abbiamo creato. Ora compila il modulo nella directory mods.
C:/ > JAVA > javac -d mods/com.tutorialspoint.greetings
src/com.tutorialspoint.greetings/module-info.java
src/com.tutorialspoint.greetings/com/tutorialspoint/greetings/Java9Tester.java
Passaggio 5
Eseguiamo il modulo per vedere il risultato. Esegui il seguente comando.
C:/ > JAVA > java --module-path mods -m com.tutorialspoint.greetings/com.tutorialspoint.greetings.Java9Tester
Qui module-path fornisce la posizione del modulo come mod e -m indica il modulo principale.
Produzione
Stamperà il seguente output sulla console.
Hello World!
REPL sta per Read-Eval-Print Loop. Con JShell, java ha la capacità REPL. Utilizzando REPL, possiamo codificare e testare la logica basata su java senza compilare usando javac e vedere direttamente il risultato dei calcoli.
Esecuzione di JShell
Apri il prompt dei comandi e digita jshell.
$ jshell
| Welcome to JShell -- Version 9-ea
| For an introduction type: /help intro
jshell>
Visualizzazione dei comandi JShell
Digita / help una volta avviato il comando jshell.
jshell> /help
| Type a Java language expression, statement, or declaration.
| Or type one of the following commands:
| /list [<name or id>|-all|-start]
| list the source you have typed
| /edit <name or id>
| edit a source entry referenced by name or id
| /drop <name or id>
| delete a source entry referenced by name or id
| /save [-all|-history|-start] <file>
| Save snippet source to a file.
| /open <file>
| open a file as source input
| /vars [<name or id>|-all|-start]
| list the declared variables and their values
| /methods [<name or id>|-all|-start]
| list the declared methods and their signatures
| /types [<name or id>|-all|-start]
| list the declared types
| /imports
| list the imported items
Esecuzione del comando JShell
Digita / imports una volta avviato il comando jshell e visualizza le importazioni utilizzate.
jshell> /imports
| import java.io.*
| import java.math.*
| import java.net.*
| import java.nio.file.*
| import java.util.*
| import java.util.concurrent.*
| import java.util.function.*
| import java.util.prefs.*
| import java.util.regex.*
| import java.util.stream.*
jshell>
Esecuzione di calcoli in JShell.
Prova a eseguire semplici calcoli in JShell.
jshell> 3+1
$1 ==> 4 jshell> 13%7 $2 ==> 6
jshell> $2 $2 ==> 6
jshell>
Creazione e utilizzo di funzioni in JShell
Crea una funzione doubled () per prendere int e restituire il suo valore raddoppiato.
jshell> int doubled(int i){ return i*2;}
| created method doubled(int)
jshell> doubled(6)
$3 ==> 12
jshell>
Uscita da JShell
Digita / esci.
jshell> /exit
| Goodbye
La documentazione Java può essere generata utilizzando lo strumento javadoc. Attualmente genera documentazione in formato html 4.0. In java 9, possiamo generare documentazione in formato html 5 utilizzando l'opzione -html5 negli argomenti della riga di comando.
Documentazione java vecchio stile
Considera il seguente codice nella cartella C: / JAVA.
Tester.java
/**
* @author MahKumar
* @version 0.1
*/
public class Tester {
/**
* Default method to be run to print
* <p>Hello world</p>
* @param args command line arguments
*/
public static void main(String []args) {
System.out.println("Hello World");
}
}
Ora esegui lo strumento javadoc di jdk 7 per generare la documentazione.
C:\JAVA>javadoc -d C:/JAVA Tester.java
Loading source file tester.java...
Constructing Javadoc information...
Standard Doclet version 1.7.0_21
Building tree for all the packages and classes...
Generating C:\JAVA\Tester.html...
Generating C:\JAVA\package-frame.html...
Generating C:\JAVA\package-summary.html...
Generating C:\JAVA\package-tree.html...
Generating C:\JAVA\constant-values.html...
Building index for all the packages and classes...
Generating C:\JAVA\overview-tree.html...
Generating C:\JAVA\index-all.html...
Generating C:\JAVA\deprecated-list.html...
Building index for all classes...
Generating C:\JAVA\allclasses-frame.html...
Generating C:\JAVA\allclasses-noframe.html...
Generating C:\JAVA\index.html...
Generating C:\JAVA\help-doc.html...
Creerà la pagina della documentazione java nella directory C: / JAVA e vedrai il seguente output.
Nuova documentazione java con supporto per la ricerca e HTML5
Esegui lo strumento javadoc di jdk 9 con il flag -html5 per generare un nuovo tipo di documentazione.
C:\JAVA> javadoc -d C:/JAVA -html5 Tester.java
Loading source file Tester.java...
Constructing Javadoc information...
Standard Doclet version 9.0.1
Building tree for all the packages and classes...
Generating C:\JAVA\Tester.html...
Generating C:\JAVA\package-frame.html...
Generating C:\JAVA\package-summary.html...
Generating C:\JAVA\package-tree.html...
Generating C:\JAVA\constant-values.html...
Building index for all the packages and classes...
Generating C:\JAVA\overview-tree.html...
Generating C:\JAVA\index-all.html...
Generating C:\JAVA\deprecated-list.html...
Building index for all classes...
Generating C:\JAVA\allclasses-frame.html...
Generating C:\JAVA\allclasses-frame.html...
Generating C:\JAVA\allclasses-noframe.html...
Generating C:\JAVA\allclasses-noframe.html...
Generating C:\JAVA\index.html...
Generating C:\JAVA\help-doc.html...
Creerà la pagina di documentazione java aggiornata nella directory D: / test e vedrai il seguente output.
In java 9, viene introdotta una nuova funzionalità in cui un formato jar è stato migliorato per avere versioni diverse della classe java o le risorse possono essere mantenute e utilizzate secondo la piattaforma. In JAR, un file MANIFEST.MF ha una voce Multi-Release: true nella sua sezione principale. La directory META-INF contiene anche una sottodirectory delle versioni le cui sottodirectory (che iniziano con 9 per Java 9) memorizzano classi specifiche della versione e file di risorse.
In questo esempio, utilizzeremo un jar multi-release per avere due versioni del file Tester.java, una per jdk 7 e una per jdk 9 e lo eseguiremo su diverse versioni di jdk.
Passi
Step 1- Crea una cartella c: / test / java7 / com / tutorialspoint. Crea Test.java con il seguente contenuto:
Tester.java
package com.tutorialspoint;
public class Tester {
public static void main(String[] args) {
System.out.println("Inside java 7");
}
}
Step 2- Crea una cartella c: / test / java9 / com / tutorialspoint. Crea Test.java con il seguente contenuto:
Tester.java
package com.tutorialspoint;
public class Tester {
public static void main(String[] args) {
System.out.println("Inside java 9");
}
}
Compila i codici sorgente.
C:\test > javac --release 9 java9/com/tutorialspoint/Tester.java
C:\JAVA > javac --release 7 java7/com/tutorialspoint/Tester.java
Crea il vaso multi-rilascio
C:\JAVA > jar -c -f test.jar -C java7 . --release 9 -C java9.
Warning: entry META-INF/versions/9/com/tutorialspoint/Tester.java,
multiple resources with same name
Corri con JDK 7
C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 7
Corri con JDK 9
C:\JAVA > java -cp test.jar com.tutorialspoint.Tester
Inside Java 9
Con Java 9, vengono aggiunti nuovi metodi di fabbrica alle interfacce List, Set e Map per creare istanze immutabili. Questi metodi factory sono metodi factory convenienza per creare una raccolta in modo meno dettagliato e conciso.
Vecchio modo per creare collezioni
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
public class Tester {
public static void main(String []args) {
Set<String> set = new HashSet<>();
set.add("A");
set.add("B");
set.add("C");
set = Collections.unmodifiableSet(set);
System.out.println(set);
List<String> list = new ArrayList<>();
list.add("A");
list.add("B");
list.add("C");
list = Collections.unmodifiableList(list);
System.out.println(list);
Map<String, String> map = new HashMap<>();
map.put("A","Apple");
map.put("B","Boy");
map.put("C","Cat");
map = Collections.unmodifiableMap(map);
System.out.println(map);
}
}
Produzione
Stamperà il seguente output.
[A, B, C]
[A, B, C]
{A=Apple, B=Boy, C=Cat}
Nuovi metodi
Con java 9, i seguenti metodi vengono aggiunti alle interfacce List, Set e Map insieme alle loro controparti sovraccariche.
static <E> List<E> of(E e1, E e2, E e3);
static <E> Set<E> of(E e1, E e2, E e3);
static <K,V> Map<K,V> of(K k1, V v1, K k2, V v2, K k3, V v3);
static <K,V> Map<K,V> ofEntries(Map.Entry<? extends K,? extends V>... entries)
Punti da notare
Per le interfacce List e Set, il metodo of (...) viene sovraccaricato per avere da 0 a 10 parametri e uno con il parametro var args.
Per l'interfaccia Map, il metodo of (...) viene sovraccaricato per avere da 0 a 10 parametri.
In caso di più di 10 parametri per l'interfaccia Map, è possibile utilizzare il metodo ofEntries (...) che accetta il parametro var args.
Nuovo modo per creare collezioni
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.AbstractMap;
import java.util.Map;
import java.util.Set;
public class Tester {
public static void main(String []args) {
Set<String> set = Set.of("A", "B", "C");
System.out.println(set);
List<String> list = List.of("A", "B", "C");
System.out.println(list);
Map<String, String> map = Map.of("A","Apple","B","Boy","C","Cat");
System.out.println(map);
Map<String, String> map1 = Map.ofEntries (
new AbstractMap.SimpleEntry<>("A","Apple"),
new AbstractMap.SimpleEntry<>("B","Boy"),
new AbstractMap.SimpleEntry<>("C","Cat"));
System.out.println(map1);
}
}
Produzione
Stamperà il seguente output.
[A, B, C]
[A, B, C]
{A=Apple, B=Boy, C=Cat}
{A=Apple, B=Boy, C=Cat}
Prima di Java 8, le interfacce possono avere i seguenti tipi di variabili / metodi.
- Variabili costanti
- Metodi astratti
Quindi non possiamo avere l'implementazione del metodo nelle interfacce o più precisamente un'implementazione predefinita prima di Java 8. Vedi l'esempio.
public class Tester {
public static void main(String []args) {
LogOracle log = new LogOracle();
log.logInfo("");
log.logWarn("");
log.logError("");
log.logFatal("");
LogMySql log1 = new LogMySql();
log1.logInfo("");
log1.logWarn("");
log1.logError("");
log1.logFatal("");
}
}
final class LogOracle implements Logging {
@Override
public void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
@Override
public void logWarn(String message) {
getConnection();
System.out.println("Log Message : " + "WARN");
closeConnection();
}
@Override
public void logError(String message) {
getConnection();
System.out.println("Log Message : " + "ERROR");
closeConnection();
}
@Override
public void logFatal(String message) {
getConnection();
System.out.println("Log Message : " + "FATAL");
closeConnection();
}
@Override
public void getConnection() {
System.out.println("Open Database connection");
}
@Override
public void closeConnection() {
System.out.println("Close Database connection");
}
}
final class LogMySql implements Logging {
@Override
public void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
@Override
public void logWarn(String message) {
getConnection();
System.out.println("Log Message : " + "WARN");
closeConnection();
}
@Override
public void logError(String message) {
getConnection();
System.out.println("Log Message : " + "ERROR");
closeConnection();
}
@Override
public void logFatal(String message) {
getConnection();
System.out.println("Log Message : " + "FATAL");
closeConnection();
}
@Override
public void getConnection() {
System.out.println("Open Database connection");
}
@Override
public void closeConnection() {
System.out.println("Close Database connection");
}
}
interface Logging {
String ORACLE = "Oracle_Database";
String MYSQL = "MySql_Database";
void logInfo(String message);
void logWarn(String message);
void logError(String message);
void logFatal(String message);
void getConnection();
void closeConnection();
}
Produzione
Vedrai il seguente output.
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Nell'esempio precedente, ogni metodo di log ha la propria implementazione. Con Java 8 le interfacce possono avere i seguenti tipi di variabili / metodi.
- Variabili costanti
- Metodi astratti
- Metodi predefiniti
- Metodi statici
Facciamo implementazione predefinita e metodi statici nell'interfaccia stessa usando Java 8.
public class Tester {
public static void main(String []args) {
LogOracle log = new LogOracle();
log.logInfo("");
log.logWarn("");
log.logError("");
log.logFatal("");
LogMySql log1 = new LogMySql();
log1.logInfo("");
log1.logWarn("");
log1.logError("");
log1.logFatal("");
}
}
final class LogOracle implements Logging {
}
final class LogMySql implements Logging {
}
interface Logging {
String ORACLE = "Oracle_Database";
String MYSQL = "MySql_Database";
default void logInfo(String message) {
getConnection();
System.out.println("Log Message : " + "INFO");
closeConnection();
}
default void logWarn(String message) {
getConnection();
System.out.println("Log Message : " + "WARN");
closeConnection();
}
default void logError(String message) {
getConnection();
System.out.println("Log Message : " + "ERROR");
closeConnection();
}
default void logFatal(String message) {
getConnection();
System.out.println("Log Message : " + "FATAL");
closeConnection();
}
static void getConnection() {
System.out.println("Open Database connection");
}
static void closeConnection() {
System.out.println("Close Database connection");
}
}
Produzione
Vedrai il seguente output.
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
Nell'esempio sopra, abbiamo di nuovo la ripetizione. Con Java 9 le interfacce possono avere i seguenti tipi di variabili / metodi.
- Variabili costanti
- Metodi astratti
- Metodi predefiniti
- Metodi statici
- Metodi privati
- Metodi statici privati
Disponiamo di metodi privati e li usiamo in Java 9.
public class Tester {
public static void main(String []args) {
LogOracle log = new LogOracle();
log.logInfo("");
log.logWarn("");
log.logError("");
log.logFatal("");
LogMySql log1 = new LogMySql();
log1.logInfo("");
log1.logWarn("");
log1.logError("");
log1.logFatal("");
}
}
final class LogOracle implements Logging {
}
final class LogMySql implements Logging {
}
interface Logging {
String ORACLE = "Oracle_Database";
String MYSQL = "MySql_Database";
private void log(String message, String prefix) {
getConnection();
System.out.println("Log Message : " + prefix);
closeConnection();
}
default void logInfo(String message) {
log(message, "INFO");
}
default void logWarn(String message) {
log(message, "WARN");
}
default void logError(String message) {
log(message, "ERROR");
}
default void logFatal(String message) {
log(message, "FATAL");
}
private static void getConnection() {
System.out.println("Open Database connection");
}
private static void closeConnection() {
System.out.println("Close Database connection");
}
}
Produzione
Vedrai il seguente output.
Open Database connection
Log Message : INFO
Close Database connection
Open Database connection
Log Message : WARN
Close Database connection
Open Database connection
Log Message : ERROR
Close Database connection
Open Database connection
Log Message : FATAL
Close Database connection
In Java 9 Process API, responsabile del controllo e della gestione dei processi del sistema operativo, è stata notevolmente migliorata. ProcessHandle Class ora fornisce l'ID del processo nativo del processo, l'ora di inizio, il tempo di CPU accumulato, gli argomenti, il comando, l'utente, il processo padre e i discendenti. La classe ProcessHandle fornisce anche un metodo per controllare la vivacità dei processi e per distruggere i processi. Ha il metodo onExit, la classe CompletableFuture può eseguire l'azione in modo asincrono quando il processo termina.
Tester.java
import java.time.ZoneId;
import java.util.stream.Stream;
import java.util.stream.Collectors;
import java.io.IOException;
public class Tester {
public static void main(String[] args) throws IOException {
ProcessBuilder pb = new ProcessBuilder("notepad.exe");
String np = "Not Present";
Process p = pb.start();
ProcessHandle.Info info = p.info();
System.out.printf("Process ID : %s%n", p.pid());
System.out.printf("Command name : %s%n", info.command().orElse(np));
System.out.printf("Command line : %s%n", info.commandLine().orElse(np));
System.out.printf("Start time: %s%n",
info.startInstant().map(i -> i.atZone(ZoneId.systemDefault())
.toLocalDateTime().toString()).orElse(np));
System.out.printf("Arguments : %s%n",
info.arguments().map(a -> Stream.of(a).collect(
Collectors.joining(" "))).orElse(np));
System.out.printf("User : %s%n", info.user().orElse(np));
}
}
Produzione
Vedrai il seguente output.
Process ID : 5800
Command name : C:\Windows\System32\notepad.exe
Command line : Not Present
Start time: 2017-11-04T21:35:03.626
Arguments : Not Present
User: administrator
I flussi sono stati introdotti in Java per aiutare gli sviluppatori a eseguire operazioni aggregate da una sequenza di oggetti. Con Java 9, vengono aggiunti pochi metodi in più per migliorare i flussi.
takeWhile (Predicate Interface)
Sintassi
default Stream<T> takeWhile(Predicate<? super T> predicate)
Il metodo takeWhile accetta tutti i valori finché il predicato non restituisce false. Restituisce, in caso di flusso ordinato, un flusso costituito dal prefisso più lungo di elementi presi da questo flusso che corrispondono al predicato dato.
Esempio
import java.util.stream.Stream;
public class Tester {
public static void main(String[] args) {
Stream.of("a","b","c","","e","f").takeWhile(s->!s.isEmpty())
.forEach(System.out::print);
}
}
Produzione
takeWhile metodo accetta tutti i valori a, be c, quindi una volta che la stringa è vuota, ha smesso di essere eseguito.
abc
dropWhile (Predicate Interface)
Sintassi
default Stream<T> dropWhile(Predicate<? super T> predicate)
Il metodo dropWhile elimina tutti i valori all'inizio finché il predicato non restituisce true. Restituisce, in caso di flusso ordinato, un flusso costituito dagli elementi rimanenti di questo flusso dopo aver eliminato il prefisso più lungo di elementi corrispondenti al predicato dato.
Esempio
import java.util.stream.Stream;
public class Tester {
public static void main(String[] args) {
Stream.of("a","b","c","","e","f").dropWhile(s-> !s.isEmpty())
.forEach(System.out::print);
System.out.println();
Stream.of("a","b","c","","e","","f").dropWhile(s-> !s.isEmpty())
.forEach(System.out::print);
}
}
Produzione
drop Mentre il metodo elimina i valori a, bec, quindi una volta che la stringa è vuota, prende tutti i valori.
ef
ef
iterare
Sintassi
static <T> Stream<T> iterate(T seed, Predicate<? super T> hasNext, UnaryOperator<T> next)
Il metodo iterate ora ha il predicato hasNext come parametro che arresta il ciclo una volta che il predicato hasNext restituisce false.
Esempio
import java.util.stream.IntStream;
public class Tester {
public static void main(String[] args) {
IntStream.iterate(3, x -> x < 10, x -> x+ 3).forEach(System.out::println);
}
}
Produzione
3
6
9
ofNullable
Sintassi
static <T> Stream<T> ofNullable(T t)
Il metodo ofNullable viene introdotto per prevenire NullPointerExceptions e per evitare controlli null per i flussi. Questo metodo restituisce un flusso sequenziale contenente un singolo elemento, se non nullo, altrimenti restituisce un flusso vuoto.
Esempio
import java.util.stream.Stream;
public class Tester {
public static void main(String[] args) {
long count = Stream.ofNullable(100).count();
System.out.println(count);
count = Stream.ofNullable(null).count();
System.out.println(count);
}
}
Produzione
1
0
L'istruzione try-with-resources è un'istruzione try con una o più risorse debitamente dichiarate. Qui la risorsa è un oggetto che dovrebbe essere chiuso una volta che non è più necessario. L'istruzione try-with-resources garantisce che ogni risorsa venga chiusa al termine del requisito. Qualsiasi oggetto che implementa java.lang.AutoCloseable o java.io.Closeable, interfaccia può essere utilizzato come risorsa.
Prima di Java 9, le risorse devono essere dichiarate prima di try o all'interno dell'istruzione try come mostrato di seguito nell'esempio fornito. In questo esempio, useremo BufferedReader come risorsa per leggere una stringa e poi BufferedReader deve essere chiuso.
Tester.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class Tester {
public static void main(String[] args) throws IOException {
System.out.println(readData("test"));
}
static String readData(String message) throws IOException {
Reader inputString = new StringReader(message);
BufferedReader br = new BufferedReader(inputString);
try (BufferedReader br1 = br) {
return br1.readLine();
}
}
}
Produzione
test
Qui dobbiamo dichiarare una risorsa br1 all'interno dell'istruzione try e quindi usarla. In Java9, non è più necessario dichiarare br1 e il programma successivo darà lo stesso risultato.
Tester.java
import java.io.BufferedReader;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
public class Tester {
public static void main(String[] args) throws IOException {
System.out.println(readData("test"));
}
static String readData(String message) throws IOException {
Reader inputString = new StringReader(message);
BufferedReader br = new BufferedReader(inputString);
try (br) {
return br.readLine();
}
}
}
Produzione
test
@ L'annotazione precedente è stata introdotta nella versione java 5. Un elemento del programma annotato con @Deprecated significa che non dovrebbe essere usato per nessuno dei seguenti motivi:
- Il suo utilizzo può portare a errori.
- Potrebbe essere incompatibile nella versione futura.
- Potrebbe essere rimosso nella versione futura.
- Un'alternativa migliore ed efficiente l'ha sostituita.
Il compilatore genera avvisi ogni volta che viene utilizzato un elemento deprecato. Con Java 9, vengono apportati due nuovi miglioramenti all'annotazione @Deprecated.
forRemoval- Indica se l'elemento annotato è soggetto a rimozione in una versione futura. Il valore predefinito è falso.
since- Restituisce la versione in cui l'elemento annotato è diventato obsoleto. Il valore predefinito è la stringa vuota.
Deprecato con da allora
L'esempio seguente della classe booleana javadoc su Java 9 illustra l'uso dell'attributo since nell'annotazione @Deprecated.
Classe booleana
Deprecato con forRemoval
Il seguente esempio di javadoc della classe di sistema su Java 9 illustra l'uso dell'attributo forRemoval sull'annotazione @Deprecated.
Classe di sistema
L'operatore Diamond è stato introdotto in java 7 per rendere il codice più leggibile ma non può essere utilizzato con le classi interne anonime. In java 9, può essere utilizzato anche con una classe anonima per semplificare il codice e migliorare la leggibilità. Considera il codice seguente prima di Java 9.
Tester.java
public class Tester {
public static void main(String[] args) {
Handler<Integer> intHandler = new Handler<Integer>(1) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler.handle();
Handler<? extends Number> intHandler1 = new Handler<Number>(2) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler1.handle();
Handler<?> handler = new Handler<Object>("test") {
@Override
public void handle() {
System.out.println(content);
}
};
handler.handle();
}
}
abstract class Handler<T> {
public T content;
public Handler(T content) {
this.content = content;
}
abstract void handle();
}
Produzione
1
2
Test
Con Java 9, possiamo usare l'operatore <> con la classe anonima come mostrato di seguito.
Tester.java
public class Tester {
public static void main(String[] args) {
Handler<Integer> intHandler = new Handler<>(1) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler.handle();
Handler<? extends Number> intHandler1 = new Handler<>(2) {
@Override
public void handle() {
System.out.println(content);
}
};
intHandler1.handle();
Handler<?> handler = new Handler<>("test") {
@Override
public void handle() {
System.out.println(content);
}
};
handler.handle();
}
}
abstract class Handler<T> {
public T content;
public Handler(T content) {
this.content = content;
}
abstract void handle();
}
Produzione
1
2
Test
La classe facoltativa è stata introdotta in Java 8 per evitare controlli null e problemi di NullPointerException. In Java 9, vengono aggiunti tre nuovi metodi per migliorarne le funzionalità.
- stream()
- ifPresentOrElse()
- or()
metodo stream ()
Sintassi
public Stream<T> stream()
Se è presente un valore, restituisce uno Stream sequenziale contenente solo quel valore, altrimenti restituisce uno Stream vuoto.
Esempio
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Tester {
public static void main(String[] args) {
List<Optional<String>> list = Arrays.asList (
Optional.empty(),
Optional.of("A"),
Optional.empty(),
Optional.of("B"));
//filter the list based to print non-empty values
//if optional is non-empty, get the value in stream, otherwise return empty
List<String> filteredList = list.stream()
.flatMap(o -> o.isPresent() ? Stream.of(o.get()) : Stream.empty())
.collect(Collectors.toList());
//Optional::stream method will return a stream of either one
//or zero element if data is present or not.
List<String> filteredListJava9 = list.stream()
.flatMap(Optional::stream)
.collect(Collectors.toList());
System.out.println(filteredList);
System.out.println(filteredListJava9);
}
}
Produzione
[A, B]
[A, B]
ifPresentOrElse () metodo
Sintassi
public void ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
Se è presente un valore, esegue l'azione data con il valore, altrimenti esegue l'azione a base vuota data.
Esempio
import java.util.Optional;
public class Tester {
public static void main(String[] args) {
Optional<Integer> optional = Optional.of(1);
optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->
System.out.println("Not Present."));
optional = Optional.empty();
optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() ->
System.out.println("Not Present."));
}
}
Produzione
Value: 1
Not Present.
o () metodo
Sintassi
public Optional<T> or(Supplier<? extends Optional<? extends T>> supplier)
Se è presente un valore, restituisce un Opzionale che descrive il valore, altrimenti restituisce un Opzionale prodotto dalla funzione di fornitura.
Esempio
import java.util.Optional;
import java.util.function.Supplier;
public class Tester {
public static void main(String[] args) {
Optional<String> optional1 = Optional.of("Mahesh");
Supplier<Optional<String>> supplierString = () -> Optional.of("Not Present");
optional1 = optional1.or( supplierString);
optional1.ifPresent( x -> System.out.println("Value: " + x));
optional1 = Optional.empty();
optional1 = optional1.or( supplierString);
optional1.ifPresent( x -> System.out.println("Value: " + x));
}
}
Produzione
Value: Mahesh
Value: Not Present
Con Java 9, è stata introdotta una nuova API di immagini multi-risoluzione che supporta più immagini con diverse varianti di risoluzione. Questa API consente di utilizzare un insieme di immagini con una risoluzione diversa come un'unica immagine a più risoluzioni. Di seguito sono riportate le principali operazioni di immagine multi-risoluzione.
Image getResolutionVariant(double destImageWidth, double destImageHeight) - Ottiene un'immagine specifica che è la variante migliore per rappresentare questa immagine logica alla dimensione indicata.
List<Image> getResolutionVariants() - Ottiene un elenco leggibile di tutte le varianti di risoluzione.
Esempio
import java.io.IOException;
import java.net.URL;
import java.net.MalformedURLException;
import java.util.ArrayList;
import java.util.List;
import java.awt.Image;
import java.awt.image.MultiResolutionImage;
import java.awt.image.BaseMultiResolutionImage;
import javax.imageio.ImageIO;
public class Tester {
public static void main(String[] args) throws IOException, MalformedURLException {
List<String> imgUrls = List.of("http://www.tutorialspoint.com/java9/images/logo.png",
"http://www.tutorialspoint.com/java9/images/mini_logo.png",
"http://www.tutorialspoint.com/java9/images/large_logo.png");
List<Image> images = new ArrayList<Image>();
for (String url : imgUrls) {
images.add(ImageIO.read(new URL(url)));
}
// read all images into one multiresolution image
MultiResolutionImage multiResolutionImage =
new BaseMultiResolutionImage(images.toArray(new Image[0]));
// get all variants of images
List<Image> variants = multiResolutionImage.getResolutionVariants();
System.out.println("Total number of images: " + variants.size());
for (Image img : variants) {
System.out.println(img);
}
// get a resolution-specific image variant for each indicated size
Image variant1 = multiResolutionImage.getResolutionVariant(156, 45);
System.out.printf("\nImage for destination[%d,%d]: [%d,%d]",
156, 45, variant1.getWidth(null), variant1.getHeight(null));
Image variant2 = multiResolutionImage.getResolutionVariant(311, 89);
System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 311, 89,
variant2.getWidth(null), variant2.getHeight(null));
Image variant3 = multiResolutionImage.getResolutionVariant(622, 178);
System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 622, 178,
variant3.getWidth(null), variant3.getHeight(null));
Image variant4 = multiResolutionImage.getResolutionVariant(300, 300);
System.out.printf("\nImage for destination[%d,%d]: [%d,%d]", 300, 300,
variant4.getWidth(null), variant4.getHeight(null));
}
}
Produzione
Total number of images: 3
BufferedImage@7ce6a65d: type = 6 ColorModel: #pixelBits = 32 numComponents = 4
color space =java.awt.color.ICC_ColorSpace@548ad73b transparency = 3
has alpha = true isAlphaPre = false ByteInterleavedRaster: width =311
height = 89 #numDataElements 4 dataOff[0] = 3
BufferedImage@4c762604: type = 6 ColorModel: #pixelBits = 32 numComponents = 4
color space =java.awt.color.ICC_ColorSpace@548ad73b transparency = 3
has alpha = true isAlphaPre = false ByteInterleavedRaster: width =156
height = 45 #numDataElements 4 dataOff[0] = 3
BufferedImage@2641e737: type = 6 ColorModel: #pixelBits = 32 numComponents = 4
color space =java.awt.color.ICC_ColorSpace@548ad73b transparency = 3
has alpha = true isAlphaPre = false ByteInterleavedRaster: width =622
height = 178 #numDataElements 4 dataOff[0] = 3
Image for destination[156,45]: [311,89]
Image for destination[311,89]: [311,89]
Image for destination[622,178]: [622,178]
Image for destination[300,300]: [622,178]
La classe CompletableFuture è stata introdotta in Java 8 per rappresentare il futuro che può essere completato impostando il suo valore e lo stato esplicitamente. Può essere utilizzato come java.util.concurrent.CompletionStage. Supporta funzioni e azioni dipendenti che sono state attivate al completamento del futuro. In java 9 l'API CompletableFuture è stata ulteriormente migliorata. Di seguito sono riportate le modifiche pertinenti apportate all'API.
- Supporto per ritardi e timeout.
- Supporto migliorato per le sottoclassi.
- Aggiunti nuovi metodi di fabbrica.
Supporto per ritardi e timeout
public CompletableFuture<T> completeOnTimeout(T value, long timeout, TimeUnit unit)
Questo metodo completa questo CompletableFuture con il valore specificato se non viene completato altrimenti prima del timeout specificato.
public CompletableFuture<T> orTimeout(long timeout, TimeUnit unit)
Questo metodo completa in modo eccezionale questo CompletableFuture con un'eccezione TimeoutException se non viene completato altrimenti prima del timeout specificato.
Supporto migliorato per le sottoclassi
public Executor defaultExecutor()
Restituisce l'Executor predefinito utilizzato per i metodi asincroni che non specificano un Executor. Questo metodo può essere sovrascritto nelle sottoclassi per restituire un Executor per fornire un thread indipendente come minimo.
public <U> CompletableFuture<U> newIncompleteFuture()
Restituisce un nuovo CompletableFuture incompleto del tipo che deve essere restituito da un metodo CompletionStage. Le sottoclassi della classe CompletableFuture devono sovrascrivere questo metodo per restituire un'istanza della stessa classe di CompletableFuture. L'implementazione predefinita restituisce un'istanza della classe CompletableFuture.
Nuovi metodi di fabbrica
public static <U> CompletableFuture<U> completedFuture(U value)
Questo metodo factory restituisce un nuovo CompletableFuture che è già completato con il valore specificato.
public static <U> CompletionStage<U> completedStage(U value)
Questo metodo factory restituisce un nuovo CompletionStage che è già completato con il valore dato e supporta solo i metodi presenti nell'interfaccia CompletionStage.
public static <U> CompletionStage<U> failedStage(Throwable ex)
Questo metodo factory restituisce un nuovo CompletionStage che è già completato eccezionalmente con la data eccezione e supporta solo i metodi presenti nell'interfaccia CompletionStage.
Oltre alle funzionalità menzionate, con Java 9 vengono apportati molti più miglioramenti alla piattaforma JDK. Alcuni di loro sono elencati di seguito.
- Miglioramenti a GC (Garbage Collector)
- API Stack-Walking
- Filtra i dati di serializzazione in entrata
- Ritira l'applet API
- Indica la concatenazione di stringhe
- Maniglie del metodo migliorate
- API e servizio di registrazione della piattaforma Java
- Corde compatte
- Parser API per Nashorn