Chi ha paura di Java?
L’oscuro signore è tornato: colui che non può essere nominato, ovvero Oracle, fa uscire la sua nuova versione di Java, la numero 7.
Il 30 Settembre 2004 esce la versione 1.5, talmente rivoluzionaria da essere denominata “versione 5”: introduceva i Generics, il nuovo Enhanced for each loop, gli Enumerati, i Varargs, l’Autoboxing/unboxing e i metadati più amati dagli sviluppatori: le Annotations.
L’11 Dicembre 2006 esce la versione 6, con diverse migliorie e ottimizzazioni, oltre al supporto per JDBC 4.0 (JSR 221).
Il 28 Luglio 2011, a circa 4 anni e mezzo di distanza dalla precedente versione, ecco uscire la versione 7. E la sorpresa è: non interessa a nessuno! Non avrà mica a che fare col fatto che la Sun è stata acquisita dall’oscuro signore? Quel poco che si legge in rete è in chiave abbastanza polemico: troppo tempo per la nuova versione, troppo poche le novità introdotte. Chissà….io propongo ai miei cari lettori di non curarci delle polemiche e degli odi faziosi e di andare a vedere insieme le novità di un linguaggio che comunqe gira su miliardi di dispositivi sparsi per il mondo, che ne dite?
Horcrux numero 1: switcha la stringa!
Avete mai voluto usare lo switch
con le stringhe? Finora non era possibile purtroppo…ad esempio si doveva scrivere qualcosa del genere:
if (linguaggio.equals("java") || linguaggio.equals("scala")) { System.out.println("Statico!"); } else if (linguaggio.equals("groovy")) { System.out.println("Dinamico"); } else if (linguaggio.equals("clojure")) { System.out.println("Funzionale"); } else { System.out.println("Che linguaggio hai detto?"); }
Ora non più: provate a scrivere il codice sopra riportato in Netbeans 7 (l’ide che a tutt’ora supporta la JDK 7, è questione di poco prima che venga supportato anche da Eclipse Indigo) e….Expelliarmus!…appare una iconcina che ci propone di convertire il codice al nuovo switch. Cliccandola otteniamo:
switch (linguaggio) { case "java": case "scala": System.out.println("Statico!"); break; case "groovy": System.out.println("Dinamico"); break; case "clojure": System.out.println("Funzionale"); break; default: System.out.println("Che linguaggio hai detto?"); break; }
Bello, no? Non solo il codice è più leggibile, ma il bytecode generato risulta anche più efficiente, sfruttando l'equals
sull’hashcode
della stringa!
Horcrux numero 2: provaci meglio e chiudi da solo!
Una delle critiche spesso mossa a Java è questa: “ma quanto è verboso, quanto codice bisogna scrivere per fare poche cose!” Beh, chi ha programmato per un po’ di tempo in Assembly potrà sorridere, ma c’è da dire che siamo nel 2011 e che stanno prendendo campo dei nuovi linguaggi davvero potenti e compatti, come Scala.
Java 7 introduce la possibilità di chiudere in modo automatico le risorse, riducendo di molto il cosiddetto boiler plate code. Esempio: scriviamo un programma che legge un file e chiude il FileInputStream
quando ha terminato. Il codice potrebbe essere il seguente:
public class ReadFile { public static void main(String[] args) { // devo dichiarare qua inputStream perché // sia visibile nel finally InputStream inputStream = null; try { inputStream = new FileInputStream(new File("Voldemort.txt")); // lettura del file } catch (IOException ex) { System.out.println("Gestire l'errore " + ex.getMessage()); } finally { // che la lettura del file vada a buon fine o no // devo chiudere l'InputStream if (inputStream != null) inputStream.close(); } }
C’è un errore, direte voi: close
può a sua volta causare una IOException
che deve essere gestita:
public static void main(String[] args) { InputStream inputStream = null; try { inputStream = new FileInputStream(new File("Voldemort.txt")); // lettura del file } catch (IOException ex) { System.out.println("Gestire l'errore " + ex.getMessage()); } finally { if (inputStream != null) { try { inputStream.close(); } catch (IOException ex) { // questa eccezione la sopprimo } } } }
Quante parentesi graffe, e solo per leggere un file, vi direbbero i seguaci di Serpeverde (i Pythonisti!). E ancora non abbiamo finito: l’eccezione sopressa non è accessibile dal codice chiamante; è vero che non so in quanti casi interessi avere accesso sia all’eccezione originale che all’eccezione generata dal blocco finally
, ma se volessimo le cose si complicherebbero ulterioriormente: dovremmo ricorrere al ThreadLocal
per memorizzare l’eccezione del finally
e così via. Java 7, aiutami tu!
In Java 7 la lettura di un file si fa come segue:
public static void main(String[] args) { try (InputStream inputStream = new FileInputStream(new File("Voldemort.txt"))) { //leggere il file } catch (IOException ex) { System.out.println("Gestire l'errore " + ex.getMessage()); } }
Il try
può ora essere seguito da uno o più statement tra parentesi tonde: ciascuno di questi statement deve creare un oggetto che implementi la nuova interfaccia java.lang.AutoClosable
. Questa possiede un solo metodo:
void close() throws Exception;
Ogni risorsa AutoClosable
creata nel try
sarà chiusa automaticamente! Se vengono lanciate due eccezioni, una dentro il blocco try
e una in fase di chiusura della risorsa, la prima eccezione è quella lanciata al chiamante. Tuttavia la seconda è anch’essa accessibile tramite il nuovo metodo ex.getSupressed()
, aggiunto su Throwable
in Java 7.
Conclusioni
I primi due Horcrux sono stati scoperti, ma ancora diversi altri attendono di essere svelati! Nei prossimi post continueremo la nostra avventurosa ricerca.
Alla prossima!
Pingback: ()