Java 7 e i Doni Tardivi – Prima Parte

Chi ha paura di Java?

Evil JavaL’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!

Manuele Piastra

Sono uno Scrum Master e Project Manager i cui skill tecnici sono focalizzati al momento sullo sviluppo di applicazioni Java EE su IBM Websphere 7.0 utilizzando JSF (RichFaces), JPA (EclipseLink) ed EJB3. Presso OmniaGroup ricopro il ruolo di Training Manager: seleziono il personale tecnico, mi occupo della sua crescita formativa organizzando Corsi e Workshop sia interni che esterni, molti dei quali hanno visto me come docente. LinkedIn Profile - Google+