Writing a parametrized method where parameter has to be parametrized again

Viewed 51

I am working with Websockets in java. I have to implement a method that takes in a generic message handler. So I wrote like this and it compiles.

public <T, M extends MessageHandler> boolean addMessageHandler(Class<T> clazz, M messageHandler) {
}

But when I try to be more specific, it throws compile time errors.

public <T, M<T> extends MessageHandler> boolean addMessageHandler(Class<T> clazz, M<T> messageHandler) {
}

Errors I get:

  1. Cannot resolve symbol 'T'
  2. '>' expected.

How can I solve this issue?

The MessageHandler interface looks like this and this is a library method so I can't alter:

public interface MessageHandler {

    interface Partial<T> extends javax.websocket.MessageHandler {
        void onMessage(T messagePart, boolean last);
    }

    interface Whole<T> extends javax.websocket.MessageHandler {
        void onMessage(T message);
    }
}
1 Answers

Java does not support this kind of composite generics. There is a workaround though:

  1. Define a marker interface with the generic type T:
    interface Handler<T> {}
    
  2. Define interfaces extending the provided interfaces that cannot be changed and the marker interface:
    interface PartialMessageHandler<T> extends MessageHandler.Partial<T>, 
                                               Handler<T> {}
    
    interface WholeMessageHandler<T> extends MessageHandler.Whole<T>, 
                                             Handler<T> {}
    
  3. Redefine your method like this:
    public <T, M extends Handler<T>> boolean addMessageHandler(Class<T> clazz, M messageHandler) {
        return true;
    }
    
Related