Sarò specifico: Java 8 è promesso di portare tra le altre espressioni lambda nonché riferimenti al metodo e al costruttore. Come sviluppatore Java sono molto contento di questo.
Nella mia programmazione quotidiana vedo sempre più opportunità in cui l'utilizzo di queste funzionalità semplificherebbe enormemente il codice che altrimenti sarebbe molto prolisso e noioso. Invece di riferimenti al metodo e al costruttore, ho iniziato a usare sempre più riflessioni e ho pianificato di migrare quei percorsi di codice in Java 8 il prima possibile. Uso commenti speciali (come i ben noti commenti di TODO: JAVA8) che possono essere utilizzati dall'IDE o facilmente aperti per trovare i luoghi pertinenti. Inoltre, eseguo test approfonditi su tutti i casi per assicurarmi che funzionino.
Ma devo ancora chiedermi se sia bello farlo in quel modo. È accettabile produrre un codice un po 'più fragile ora che alla fine diventerà di nuovo robusto? GA per Java 8 è settembre 2013, quindi non è troppo lontano nel futuro (a condizione che la data di rilascio non scorra).
Un esempio generico dovrebbe essere qualcosa del genere: voglio creare alcuni oggetti contenitore e riempirli con dati da un database. Se dovessi usare l'approccio standard di Java, potrebbe apparire come questo:
class ContainerService { private Database database; private final Map, ContainerInitializer> INITIALIZERS = new HashMap(); { INITIALIZERS.put(Foo.class, new FooInitializer()); } public Container getContainer(Class cls) { return INITIALIZERS.get(cls).create(); } interface ContainerInitializer { Container create(); } class FooInitializer implements ContainerInitializer { Container create() { return new Container(database.getFoo()); } } }
Il codice riflettente è
class ContainerService { private Database database; private final Map, String> INITIALIZERS = new HashMap(); { INITIALIZERS.put(Foo.class, "getFoo"); } public Container getContainer(Class cls) { Method m = Database.class.getMethod(INITIALIZERS.get(cls)); return new Container(m.invoke(database)); } }
Nota come tutte le interfacce e le classi intermedie cadono.
La variante Java 8 è qualcosa che segue le seguenti linee:
class ContainerService { private Database database; private final Map, ContainerInitializer> INITIALIZERS = new HashMap(); { INITIALIZERS.put(Foo.class, database::getFoo); } public Container getContainer(Class cls) { return new Container(INITIALIZER.get(cls).create()); } private interface ContainerInitializer { Container create(); } }
Questo è leggermente più lungo di nuovo ma ha la sicurezza del tipo. Inoltre è banale ottenere dal codice preparato il codice finale usando i riferimenti al metodo.
Ovviamente l'esempio è un po 'semplice. Immagina di avere molti tipi che il contenitore potrebbe contenere. Nel primo metodo, ci sarebbe una classe extra per ognuno di essi. Negli altri due metodi, devono essere aggiunti solo i dati. Mantiene tutto molto più semplice.