2016-02-29 8 views
5

Ho appena incontrato un piccolo problema peculiare:Lambda non funziona in websocket Sessione

javax.websocket.Session session = //... 
// this works 
newSession.addMessageHandler(new MessageHandler.Whole<String>() { 

    @Override 
    public void onMessage(String message) { 
     MyWebSocket.this.onMessage(message); 
    } 
}); 
// these don't work 
newSession.addMessageHandler((MessageHandler.Whole<String>) MyWebSocket.this::onMessage); 
newSession.addMessageHandler((MessageHandler.Whole<String>) message -> MyWebSocket.this.onMessage(message)); 


void onMessage(String message) { 
    System.out.println(message); 
} 

Qualcuno sa perché le espressioni lambda non funziona in questo caso? Non ci sono errori di compilazione, nessuna eccezione, niente di niente. Il metodo "onMessage" non viene semplicemente chiamato.

Uso Java 1.8.0_65 e l'implementazione di riferimento Tyrus 1.9.

risposta

2

vedere https://blogs.oracle.com/PavelBucek/entry/websocket_api_1_1_released

TLDR; è necessario utilizzare Session#addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler)

/** 
* Register to handle to incoming messages in this conversation. A maximum of one message handler per 
* native websocket message type (text, binary, pong) may be added to each Session. I.e. a maximum 
* of one message handler to handle incoming text messages a maximum of one message handler for 
* handling incoming binary messages, and a maximum of one for handling incoming pong 
* messages. For further details of which message handlers handle which of the native websocket 
* message types please see {@link MessageHandler.Whole} and {@link MessageHandler.Partial}. 
* Adding more than one of any one type will result in a runtime exception. 
* 
* @param clazz type of the message processed by message handler to be registered. 
* @param handler whole message handler to be added. 
* @throws IllegalStateException if there is already a MessageHandler registered for the same native 
*        websocket message type as this handler. 
*/ 
public void addMessageHandler(Class<T> clazz, MessageHandler.Whole<T> handler); 

al fine di utilizzare lambda come mancini messaggi.

-2

Dalla mia comprensione MessageHandler dovrebbe essere un @FunctionalInterface per consentire espressioni lambda qui, che non è il caso.

+1

["Tuttavia, il compilatore tratterà qualsiasi interfaccia che soddisfi la definizione di un'interfaccia funzionale come interfaccia funzionale indipendentemente dal fatto che sia presente o meno un'annotazione di FunctionalInterface nella dichiarazione dell'interfaccia."] (Https://docs.oracle. com/javase/8/docs/api/java/lang/FunctionalInterface.html) Non è necessario l'annotazione per usarlo come lambda –

+1

Inoltre, se fosse il caso, ci sarebbe un errore di compilazione. –