Java 8: gestione delle eccezioni controllate obbligatorie nelle espressioni lambda. Perché obbligatorio, non opzionale?

Sto giocando con le nuove funzionalità di lambda in Java 8 e ho scoperto che le pratiche offerte da Java 8 sono davvero utili. Tuttavia, mi chiedo c’è un buon modo per aggirare il problema per il seguente scenario. Supponiamo di avere un involucro del pool di oggetti che richiede una sorta di factory per riempire il pool di oggetti, ad esempio (usando java.lang.functions.Factory ):

 public class JdbcConnectionPool extends ObjectPool { public ConnectionPool(int maxConnections, String url) { super(new Factory() { @Override public Connection make() { try { return DriverManager.getConnection(url); } catch ( SQLException ex ) { throw new RuntimeException(ex); } } }, maxConnections); } } 

Dopo aver trasformato l’interfaccia funzionale in espressione lambda, il codice sopra diventa così:

 public class JdbcConnectionPool extends ObjectPool { public ConnectionPool(int maxConnections, String url) { super(() -> { try { return DriverManager.getConnection(url); } catch ( SQLException ex ) { throw new RuntimeException(ex); } }, maxConnections); } } 

Non così male, ma l’eccezione controllata java.sql.SQLException richiede un blocco try / catch all’interno del lambda. Nella mia azienda usiamo due interfacce per molto tempo:

  • IOut è equivalente a java.lang.functions.Factory ;
  • e un’interfaccia speciale per i casi che di solito richiedono la propagazione delle eccezioni controllate: interface IUnsafeOut { T out() throws E; } interface IUnsafeOut { T out() throws E; } .

Sia IOut che IUnsafeOut devono essere rimossi durante la migrazione a Java 8, tuttavia non esiste una corrispondenza esatta per IUnsafeOut . Se le espressioni lambda potrebbero gestire eccezioni controllate come se fossero deselezionate, potrebbe essere ansible utilizzare semplicemente il seguente nel costruttore sopra:

 super(() -> DriverManager.getConnection(url), maxConnections); 

Sembra molto più pulito. Vedo che posso riscrivere la super class ObjectPool per accettare il nostro IUnsafeOut , ma per quanto ne so, Java 8 non è ancora finito, quindi potrebbero esserci alcune modifiche come:

  • implementare qualcosa di simile a IUnsafeOut ? (a dire il vero, lo considero sporco: il sobject deve scegliere cosa accettare: Factory o “fabbrica non sicura” che non può avere firme di metodo compatibili)
  • semplicemente ignorando le eccezioni controllate in lambda, quindi nessuna necessità in IUnsafeOut surrogati? (perché no? ad esempio un altro importante cambiamento: OpenJDK, che uso, javac ora non richiede variabili e parametri da dichiarare come final da catturare in una class anonima [interfaccia funzionale] o espressione lambda)

Quindi la domanda è generalmente: c’è un modo per aggirare le eccezioni controllate in lambda o è programmato in futuro fino a quando Java 8 non sarà finalmente rilasciato?


Aggiornamento 1

Hm-mm, per quanto comprendo quello che abbiamo attualmente, sembra che al momento non ci sia modo, nonostante l’articolo di riferimento sia datato dal 2010: Brian Goetz spiega la trasparenza delle eccezioni in Java . Se nulla è cambiato molto in Java 8, questa potrebbe essere considerata una risposta. Anche Brian dice che l’ interface ExceptionalCallable (quello che ho citato come IUnsafeOut dal nostro codice legacy) è praticamente inutile, e sono d’accordo con lui.

Mi manca ancora qualcos’altro?