2015-07-26 4 views
5

Dato questo java 8 codiceLanciare da lambda

public Server send(String message) { 
    sessions.parallelStream() 
     .map(Session::getBasicRemote) 
     .forEach(basic -> { 
      try { 
      basic.sendText(message); 
      } catch (IOException e) { 
      e.printStackTrace(); 
      } 
     }); 

    return this; 
} 

come possiamo correttamente facciamo questa IOException essere delegato lo stack della chiamata al metodo? (In poche parole come rendere questo metodo di gettare questo IOException?)

Lambda in java non sembra molto amichevole per gestione degli errori ...

risposta

8

Il mio approccio sarebbe quello di subdolamente tiro dalla lambda, ma fate attenzione ad avere il metodo send dichiararla nella sua throws clausola. Utilizzando la classe ExceptionalI posted here:

public Server send(String message) throws IOException { 
    sessions.parallelStream() 
      .map(Session::getBasicRemote) 
      .forEach(basic -> Exceptional.from(() -> basic.sendText(message)).get()); 
    return this; 
} 

In questo modo si sta effettivamente facendo il compilatore "guardare lontano" solo per un po ', disabilitando le sue eccezioni controllo in un punto nel codice, ma dichiarando l'eccezione sul vostro send metodo, si ripristina il comportamento normale per tutti i suoi chiamanti.

+1

Oh ora mi piace. Questo è davvero molto subdolo. –

2

Il problema è infatti che tutti i @FunctionalInterface s utilizzati in lambda Non consentire eccezioni da lanciare, salvo eccezioni non controllate.

Una soluzione utilizza a package of mine; con esso, il codice può leggere:

sessions.parallelStream() 
    .map(Session::getBasicRemote) 
    .forEach(Throwing.consumer(basic -> basic.sendText(message))); 
return this; 
+0

Come si fa a "inviare" l'eccezione? –

+0

@MarkoTopolnik: lo capisco. Ma è necessario un ** lotto ** di lavoro in più per fare in modo che 'send' lanci la' IOException'. Se non sbaglio, devi fondamentalmente prendere il 'ThrownByLambdaException', e poi avere una serie di' instanceof' per capire qual è l'eccezione reale in modo che tu possa ricrearla. Forse non così male per una o due eccezioni, ma ancora piuttosto prolisso. –

+0

@ T.J.Crowder Per essere onesti con il nostro collega fge (e come hai scoperto nella nostra chat), 'throwing-lambdas' supporta l'idioma di lancio furtivo. –

5

I wrote an extension all'API Stream che consente di generare eccezioni controllate.

public Server send(String message) throws IOException { 
    ThrowingStream.of(sessions, IOException.class) 
     .parallelStream() 
     .map(Session::getBasicRemote) 
     .forEach(basic -> basic.sendText(message)); 

    return this; 
} 
+0

grazie, ora questa è davvero una bella interfaccia :) controllerà sicuramente il tuo codice sorgente – vach